仅使用正则表达式匹配最长的单词

时间:2018-03-02 15:18:59

标签: php regex preg-match

我需要使用正则表达式匹配给定字符串的最长单词: 例如给定字符串

  • S =“你好夜斧axbxbxx舞会......等等。”
  • 字符集1 = [abcdexy]
  • 字符集2 = [mnrpo]

我只需要一个与2个constriants相匹配的单词,所有单词应该只包含一组中的字符,所选单词应该是最长的,我试图用php正则表达式解决这个问题,如:

preg_match("/\b[abcdexy]+/",$s, $match1);
preg_match("/\b[mnrpo]+/",$s, $match2);
if(strlen($match1[0]) > strlen($match2[0]))
{
  //output match1[0];
}
else
{
 //output match2[0]
}

预期输出应该是axbxbxx,因为它只包含第1组中的字符,而且它是属于两组之一的字之间最长的。

我的问题是,我是否可以仅使用正则表达式来完成这项工作,而无需进行strlen()测试?

1 个答案:

答案 0 :(得分:0)

您可以编写一个使用管道匹配两个字符范围的正则表达式,然后按降序长度排序匹配的值并访问第一个元素的值。

代码:(Demo

$string='hello proxy night pom-pom-mop axe prom etc decayed';
if (preg_match_all('~\b(?:[a-exy]+|[m-pr]+)\b~', $string, $out)) {
    usort($out[0], function($a, $b) {return strlen($b) - strlen($a);});  // or spaceship operator if you like
    echo $out[0][0];
} else {
    echo "no matches";
}

输出:

decayed

上述方法不是“绑定感知”,因此如果您有两个值或更多值共享最大长度,则输出中只会得到一个值。我认为你需要构建一些额外的逻辑来处理这些边缘情况,如:

  • 输出所有最高长度值或
  • 设置次要标准以打破长度关系

我不打算编写这些解决方案扩展的代码,因为我不想去掉兔子洞。