PHP外观:获取所有文本,直到找到某个字符串

时间:2015-10-14 13:31:32

标签: php regex regex-lookarounds

我希望得到文本,直到找到某个匹配项。

例如:

我希望在找到单词the

之前获取所有文字

目前我有这条规则/([[:alnum:]|\s|.]*)(?!the)/ui

使用以下文字:

this is completely customizable through the dashboard. This is a separate area from the main c

问题是第一组匹配整行,并且在找到单词the时不会停止。我的期望是:

比赛1:this is completely customizable through
第2场比赛:dashboard. This is a separate area from

我做错了什么?

以下是sample

4 个答案:

答案 0 :(得分:1)

您只需要使用延迟匹配进行预测:

/.+?(?=\bthe\b)/s

请参阅regex demo,匹配

this is completely customizable through 
the dashboard. This is a separate area from 

s修饰符也用于强制.匹配换行符。延迟匹配意味着它将搜索最接近的the\b帮助查找整个单词the,而不是单词theater的一部分。

rexegg.com所述的延迟匹配:

  

惰性.*?保证量化点只匹配其他模式成功所需的字符数。

您的([[:alnum:]|\s|.]*)正则表达式有点不对,因为字符类中的|被视为文字管道符号。此外,.包含[:alnum:],因此,它是多余的。您可以将其写为([\s.]*),或仅使用.*(dotall,singleline)修饰符编写/s。但由于它是贪婪的(即在寻找匹配时匹配尽可能多的字符),它只会在最终the之前停止。因此,您需要使用* - 懒惰匹配,而不是*?

由于您可能对空匹配不感兴趣,*(0次或更多次出现)应替换为+(前一个子模式的一次或多次出现)。

以下是PHP demo

$re = '/.+?(?=\bthe\b)/s'; 
$str = "this is completely customizable through the dashboard. This is a separate area from the main c"; 
preg_match_all($re, $str, $matches);
print_r($matches[0]);

答案 1 :(得分:0)

*?而非*使用非贪婪。

像这样:

.*?(?=the)

比较一下 .*?(?=the)

有了这个 .*(?=the)

答案 2 :(得分:0)

你应该使用非贪婪的修饰符U大写

另外 - 尝试使用"""在第二个关闭

/([[:alnum:]|\s|.]*)(the)/Ui

检查出来

https://regex101.com/r/cF3iK0/1

答案 3 :(得分:0)

由于您要排除单词the,最好的方法是拆分字符串,而不是尝试匹配所有字词,直到这个单词:

$result = preg_split('~\bthe\b~i', $str);
array_pop($result);
print_r($result);

您需要使用array_pop删除最后一项,因为the后面没有。

旁边(?!...)表示未跟随(?=...)表示后跟