PHP preg_match(_all)用于文本范围

时间:2019-04-04 10:49:50

标签: php regex preg-match

试图获取Textrange(搜索字符串(我自己)前后的n个单词)

$text = 'Me, my dog and “myself“ are going on a vacation. Irene and myself are broke. Myself is here :P John and myself!';

 preg_match_all("/(?:[^ ]+ ){0,2}(?:[“'"(‘. ])myself(?:[“'")‘. ])(?: [^ ]+){0,2}/", $text, $matches);   

这给了我火柴:

•狗和“我自己”要走了

•我自己

但是应该是:

•狗和“我自己”要走了

•艾琳和我自己都破产了

•约翰和我自己!

请帮助我找到所有匹配的文本,范围为前2个单词和后2个单词。 不管搜索字符串(myself)还是'myself'或“ myself”之前或之后都有特殊的char或空格...

谢谢。Sepp

1 个答案:

答案 0 :(得分:1)

出现问题是由于[“'"(‘. ][“'")‘. ]都是强制性的,并且在myself之前和之后都需要一个字符。然后,myself(?:[^ ]+ ){0,2}所需的(?: [^ ]+){0,2}前后也必须有另一个空格。

您可以使用

'/(?:\S+\s+){0,2}(?:[“'"(‘.])?myself(?:[“'")‘.]?)(?:\s+\S+){0,2}/u'

或者允许在myself周围加上\p{P}使用任何标点符号:

'/(?:\S+\s+){0,2}\p{P}?myself\p{P}?(?:\s+\S+){0,2}/u'

请参见regex demo

请注意,(?:[“'"(‘.])?(?:[“'")‘.]?)(或\p{P}?)都是可选的,它们后面的?量词使regex引擎仅匹配这些样式的1或0次出现。因此,无论是否存在,都会发生匹配。

PHP demo

$text = 'Me, my dog and “myself“ are going on a vacation. Irene and myself are broke. Myself is here :P John and myself!';
if (preg_match_all('/(?:\S+\s+){0,2}\p{P}?myself\p{P}?(?:\s+\S+){0,2}/u', $text, $result)) {
    print_r($result[0]);
}

输出:

Array
(
    [0] => dog and “myself“ are going
    [1] => Irene and myself are broke.
    [2] => John and myself!
)