繁体   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