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

时间:2012-03-29 13:57:47

标签: php regex

我使用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

实现此目的的一种方法是每次在主题中找到模式时,下一次搜索应从匹配子字符串中的第二个字开始。可以构建这样的正则表达式吗?谢谢。

2 个答案:

答案 0 :(得分:1)

使用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版本时可能会遇到问题。

答案 1 :(得分:1)

而不是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