如何使用正则表达式搜索字符串是否包含列表中的至少一个单词?

时间:2018-03-03 20:27:24

标签: php regex

我有一个字符串,需要检查列表中的任何单词是否在字符串中。我的清单如下:

$keywords = array(
    "l.*ion",
    "test",
    'one',
    'two',
    'three'
);
  1. 如果我有字符This is my lion,那么我需要返回true
  2. 如果我有字符This is my lotion,那么我需要返回true
  3. 如果我有字符串This is my dandelion,则返回false
  4. 如果我有字符串This is my location,则返回true
  5. 如果我有字符串This is my test,则返回true
  6. 如果我有字符串This is my testing,则返回false
  7. 这是我的代码:

    $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时,它会返回一个值。
    我究竟做错了什么? 如果它是真的,我期待一个数值,如果它是假的,我期待错误。

1 个答案:

答案 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