簡體   English   中英

PHP Regex匹配字符串中的單詞,但不包括一個特定單詞

[英]PHP Regex match words in a string excluding one specific word

我有一個文本($ txt),一個要添加鏈接的單詞數組($ words)和一個不能替換的單詞($ wordToExclude)。

$words = array ('adipiscing','molestie','fringilla');
$wordToExclude = 'consectetur adipiscing';


$txt = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque
mattis tincidunt dolor sed consequat. Sed rutrum, mauris convallis bibendum 
dignissim, ligula sem molestie massa, vitae condimentum neque sem non tellus.
Aenean dolor enim, cursus vel sodales ac, condimentum ac erat. Quisque
lobortis libero nec arcu fringilla imperdiet. Pellentesque commodo, 
arcu et dictum tincidunt, ipsum elit molestie ipsum, ut ultricies nisl
neque in velit. Curabitur luctus dui id urna consequat vitae mattis
turpis pretium. Donec nec adipiscing velit.'

我想獲得以下結果:

$txt = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque
mattis tincidunt dolor sed consequat. Sed rutrum, mauris convallis bibendum 
dignissim, ligula sem <a href="#">molestie</a> massa, vitae condimentum neque sem non tellus.
Aenean dolor enim, cursus vel sodales ac, condimentum ac erat. Quisque
lobortis libero nec arcu <a href="#">fringilla</a> imperdiet. Pellentesque commodo, 
arcu et dictum tincidunt, ipsum elit <a href="#">molestie</a> ipsum, ut ultricies nisl
neque in velit. Curabitur luctus dui id urna consequat vitae mattis
turpis pretium. Donec nec <a href="#">adipiscing</a> velit.'
$result = preg_replace(
    '/\b                 # Word boundary
    (                    # Match one of the following:
     (?<!consectetur\s)  #  (unless preceded by "consectetur "
     adipiscing          #  adipiscing
    |                    # or
     molestie            #  molestie
    |                    # etc.
     fringilla
    )                    # End of alternation
    \b                   # Word boundary
    /ix', 
    '<a href="#">\1</a>', $subject);

Okie doke! 盡管我認為這在技術上是可行的,但我提供的解決方案在這一點上還是比較軟的:

s%(?!consectetur adipiscing)(adipiscing|molestie|fringilla)(?<!consectetur adipiscing)%<a href="#LinkBasedUpon$1">$1</a>%s

變成...

坐着, 奉獻自若 Quisque ... ligula sem molestie massa ... nec arcu fringilla imperdiet ... nec adipiscing velit。

進入...

坐着,奉獻自若。 Quisque ... ligula sem <a href="#LinkBasedUponmolestie"> s鼠</a> massa ... nec arcu <a href="#LinkBasedUponfringilla"> fringilla </a>不當... nec <a href="#LinkBasedUponadipiscing"> adipiscing </a>天鵝絨

之所以是軟解決方案,是因為它不處理部分單詞,或者其他情況下要排除的單詞不是以要匹配的單詞之一開頭或結尾。 例如,如果我們要附加到排除的“單詞”(即consectetur adipiscing elit ),則該表達式最終將與adipiscing中的consectetur adipiscing elit匹配,因為adipiscingconsectetur adipiscing elit相同或不同。

只要您的排除“單詞”( ABC )始終以要找到的單詞之一結尾或開頭( C|X|E中包含CABC以單詞C結尾),它就應該起作用。 ...)

編輯{

“不匹配”單詞必須以匹配單詞之一開頭或結尾的原因是,此解決方案在匹配之前使用否定先行,在匹配之后使用否定后退,以確保匹配的序列與不匹配的單詞不匹配(那有意義嗎?)

}

有一些解決方案,但是它們要么是處理器,要么是程序和程序,它們的工作量很大,或者成倍地增加,這取決於單詞列表的大小和所搜索文本的長度以及特定的要求,而您從未指定任何內容否則,我現在不打算討論它。 讓我知道這是否足以滿足您的情況!

我看到您正在用PHP執行此操作。 我了解您在文本中可以找到單詞數組,因此需要用鏈接替換它們。 另外,替換時需要排除一個字符串。 也許不用編寫簡潔明了而又復雜的正則表達式,盡管可能不是最好的解決方案,但這種實用的方法又如何呢?

您將任務分為多個子任務:

  1. 使用preg_match_all查找所有出現的被排除字符串的偏移量(您知道字符串長度( strlen ),並使用preg_match_allPREG_OFFSET_CAPTURE標志,您將確定確切的開始和結束-如果有多個以上)
  2. 在單詞列表上進行foreach,然后再次使用preg_match_all獲取所有需要替換為鏈接的單詞
  3. 比較您在第2步中找到的位置與在第1步中找到的位置,如果它們不在外面,請進行替換或跳過(如果您發現重疊)

它肯定不會成為一線書,但是很容易編寫代碼,以后可能也很容易閱讀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM