如何使用PHP正则表达式搜索包含重复单词的单词序列的字符串?

问题描述:

我使用PHP来计算字符串中单词序列的出现次数。在下面的示例中,我没有看到我希望看到的结果。如何使用PHP正则表达式搜索包含重复单词的单词序列的字符串?

$subject1 = " [word1 [word1 [word1 [word1 [word3 "; 
$pattern1 = preg_quote("[word1 [word1", '/'); 
echo "count of '[word1 [word1'=". preg_match_all("/(\s|^|\W)" . $pattern1 . "(?=\s|$|\W)/", $subject1, $dummy) . "<br/>"; 

$subject2 = " [word1 [word2 [word1 [word2 [word1 [helloagain "; 
$pattern2 = preg_quote("[word1 [word2 [word1", '/'); 
echo "count of '[word1 [word2 [word1'=". preg_match_all("/(\s|^|\W)" . $pattern2 . "(?=\s|$|\W)/", $subject2, $dummy) . "<br/>"; 

以上的回报:

count of '[word1 [word1'=2 
count of '[word1 [word2 [word1'=1 

我想结果是:

count of '[word1 [word1'=3 // there are 3 instances of ‘[word1 [word1’ in $subject1 
count of '[word1 [word2 [word1'=2 // // there are 2 instances of [word1 [word2 [word1’ in $subject2 

一种方式来实现,这是每一个图案在主题下一个搜索发现时间应从第二个字开始在匹配的子字符串中。这样的正则表达式可以构建吗?谢谢。

相反preg_match_all的,身份证上的preg_match使用while循环具有偏移:

$subject1 = " [word1 [word1 [word1 [word1 [word3 "; 
$pattern1 = preg_quote("[word1 [word1", '/'); 
$offset=0; 
$total=0; 
while($count = preg_match("/(?:\s|^|\W)$pattern1(?=\s|$|\W)/", $subject1, $matches, PREG_OFFSET_CAPTURE, $offset)) { 
    // summ all matches 
    $total += $count; 
    // valorisation of offset with the position of the match + 1 
    // the next preg_match will start at this position 
    $offset = $matches[0][1]+1; 
} 
echo "total=$total\n"; 

输出:

total=3 

用于第二示例中的结果是:total=2

+0

非常感谢M42,它做我想要的。 – user646234 2012-03-29 16:32:55

+0

@ user646234:不客气。 – Toto 2012-03-29 16:36:09

+0

Monir修正为M42的代码: '$ offset + = $ matches [0] [1] +1;'应该是'$ offset = $ matches [0] [1] +1;' 否则正确的结果不是在这种情况下可以找到:'$ subject1 =“这是另一个字符串[word1 [word1 [word1 [word1 [word3];''pattern1 = preg_quote(”[word1 [word1','/'); – user646234 2012-03-30 14:46:17

使用mb_substr_count

substr_count不计算重叠值,但我不知道为什么,mb_substr_count确实

$subject1 = " [word1 [word1 [word1 [word1 [word3 "; 
echo mb_substr_count($subject1, "[word1 [word1"); // 3 
echo mb_substr_count($subject1, "[word1 [word1 [word1"); // 2 

编辑:

以供将来参考,

显然mb_substr_count行为不同在PHP 5.2中比PHP 5.3更加谨慎。我想这个函数的正确行为应该与substr_count相同,只适用于多字节支持,并且由于substr_count不支持重叠,所以应该是mb_substr_count

所以,虽然这个答案适用于PHP 5.2.6,但不要使用它,否则当你更新你的PHP版本时你可能会遇到问题。

+0

mb_substr_count()返回与我自己的代码相同的结果:-( – user646234 2012-03-29 14:58:58

+0

什么是你的php版本。mine是5.2.6 – marvin 2012-03-29 15:01:21

+0

我的PHP版本是5.3.1 – user646234 2012-03-29 15:03:54