我有一个字符串,需要检查列表中的任何单词是否在字符串中。我的清单如下:
$keywords = array(
"l.*ion",
"test",
'one',
'two',
'three'
);
This is my lion
,那么我需要返回true
。This is my lotion
,那么我需要返回true
。This is my dandelion
,则返回false
。This is my location
,则返回true
。This is my test
,则返回true
。This is my testing
,则返回false
。这是我的代码:
$keywords = implode($keywords,"|");
$list= "/\b$keywords\b/i";
$my_string= "This is my testing";
preg_match($list, $my_string, $matches, PREG_OFFSET_CAPTURE);
echo $matches[0][1];
但当我This is my testing
时,它会返回一个值。
我究竟做错了什么?
如果它是真的,我期待一个数值,如果它是假的,我期待错误。
答案 0 :(得分:2)
在您当前的正则表达式\bl.*ion|test|one|two|three\b
中,第一个\b
仅影响第一个替代,而最后一个\b
仅影响最后一个替代。
此外,由于您只想将关键字的匹配限制为一个单词,因此您不能依赖.*
模式,因为.
匹配任何字符,但是换行符
您应该使用\S*
(匹配0+非空白字符,也包括标点符号)或\w*
(匹配0+字母,数字和_
)。
因此,您需要做两件事:1)重新定义$keywords
数组,2)在implode
对替代方案进行分组时,在替代方案周围使用分组构造这样第一个和最后一个\b
就可以应用于每个替代方案。
$keywords = array(
"l\w*ion", // <-- Here, a `\w` is used instead of .
"test",
'one',
'two',
'three'
);
$list= "/\b(?:" . implode($keywords,"|") . ")\b/i"; // <-- Here, the (?:...) groups alternatives
$my_string= "This is my testing";
if (preg_match($list, $my_string, $matches, PREG_OFFSET_CAPTURE)) {
echo $matches[0][1];
}
请参阅PHP demo。
现在,模式为\b(?:l\w*ion|test|one|two|three)\b
,\b
适用于所有替代方案。请参阅this regex demo。