簡體   English   中英

PHP正則表達式負前瞻

[英]php regex negative lookahead

我有4個字母的字典。 我想編寫一個正則表達式來瀏覽字典,並匹配給定一組字母的所有單詞。

假設我通過a,b,l,l 我想找到所有帶有這些字母的單詞。

我知道我可以做/[abl]{4}/但這也可以匹配帶有2 a或2 b的單詞。

我覺得我需要對未來保持負面看法。 就像是:

[l|(ab)(?!\1)]{4} 

這里的嘗試是我想要一個以l或a或b開頭而不是a或b開頭的單詞。

首先需要錨定模式以描述字符串的開始和結束位置:

對於整個字符串字符串的^開頭, $結尾)

^[abl]{4}$

或要查找較大文本中的單詞,請使用單詞邊界[A-Za-z0-9_]的字符與其他字符之間的限制)

\b[abl]{4}\b

然后,您需要說l必須出現兩次(或者ab只能出現一次,但是更復雜):

對於整個字符串:

^(?=.*l.*l)[abl]{4}$ 

較大的文字:

\b(?=\w*l\w*l)[abl]{4}\b

為了避免兩個a或b,可以使用另一個前瞻:

對於整個字符串:

^(?=.*l.*l)(?=l*al*b|l*bl*a)[abl]{4}$ 

較大的文字:

\b(?=\w*l\w*l)(?=l*al*b|l*bl*a)[abl]{4}\b

關於[l|(ab)(?!\\1)] :在字符類中,特殊的正則表達式字符或字符序列失去其特殊含義,所有字符均視為文字。 因此, [l|(ab)(?!\\1)][)(!|?1abl]相同(由於\\1是字符類中的未知轉義序列,因此反斜杠將被忽略。)

請注意,在幾個約束條件下,模式會很快變得難看。 您應該考慮另一種方法,該方法包括用\\b[abl]{4}\\b捕獲所有單詞並再次對其進行過濾(例如,使用count_chars )。

$str ='abll labl ball aabl lblabla 1234';

$dict = 'abll';
$count = count_chars($dict);

$result = [];
if (preg_match_all('~\b[abl]{4}\b~', $str, $matches)) {
    $result = array_filter($matches[0], function ($i) use ($count) {
        return $count == count_chars($i);
    });
}

print_r($result);

如果要動態指定字母,然后生成將完成所有工作的regexp-這將是一項非常昂貴的工作。

簡單方法:您可以生成簡單的正則表達式,例如/^[abl]{4}$/ ,從字典中獲取與他匹配的所有單詞,然后分別驗證每個單詞-檢查字母數量。

更有效的方法:您可以使用以下字母排序列表在字典中為單詞建立索引:

word: apple | index: aelpp

word: pale | index: aelp

等等。 要從字母列表中獲取所有單詞,您只需對這些字母進行排序並找到具有“ index”值的完全匹配項。

編輯:所以對於47個字母,它將是

\\b(?:((?(1)(?!))l1)|((?(2)(?!))l2)|...|((?(47)(?!))l47)){47}\\b

字母可以是重復的,例如4 a和15 r(但不能再重復),等等...
不受排列的影響


要僅匹配一次故障訂單項,
使用條件允許每個項目匹配一次,
但沒有更多。

它並不復雜,並且不受排列的影響。

每次都能工作!

\\b(?:((?(1)(?!))a)|((?(2)(?!))b)|((?(3)(?!))l)|((?(4)(?!))l)){4}\\b

擴展

 \b 
 (?:
      (                             # (1)
           (?(1)(?!))
           a 
      )

   |  
      (                             # (2)
           (?(2)(?!))
           b 
      )
   |  
      (                             # (3)
           (?(3)(?!))
           l 
      )
   |  
      (                             # (4)
           (?(4)(?!))
           l 
      )
 ){4}
 \b  

暫無
暫無

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

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