用于获取仅包含模式列表中单词的字符串的正则表达式?
Posted
技术标签:
【中文标题】用于获取仅包含模式列表中单词的字符串的正则表达式?【英文标题】:Regex for getting strings that contains only the words from the pattern list? 【发布时间】:2019-03-10 04:09:43 【问题描述】:考虑以下数组元素
1.benclinton
2.clintonharry
3.harryben
4.benwill
5.jasonsmith
6.smithclinton
假设模式列表是ben,harry,clinton,那么我应该得到的结果是
1.benclinton
2.clintonharry
3.harryben
因此,基本上结果应该包含仅包含模式列表中的单词的字符串。顺序不重要
此外,每个字符串不会超过两个单词。也就是说,本史密斯永远不会成为案例。
由于我所有的字符串都在一个数组中,我想在 php 中使用 preg_grep 来执行此操作,但我对为此构建正确的正则表达式感到震惊。
什么正则表达式可以做到这一点?除了正则表达式匹配之外,还有其他有效的方法可以完成这项工作吗?
提前致谢!
【问题讨论】:
【参考方案1】:类似的东西
$names_list = ['benclinton','clintonharry','harryben','benwill','jasonsmith','smithclinton'];
$names = ['ben','harry','clinton'];
$matches = preg_grep('/('.implode('|',$names).')(?1)/', $names_list);
//- /(ben|harry|clinton)(?1)/ -- (?1) = recurse capture group 1
print_r($matches);
输出
Array
(
[0] => benclinton
[1] => clintonharry
[2] => harryben
)
Sandbox
这要求至少有两个名称(即使是同一个 2x)匹配。但在这种情况下,这是给定的,否则一切都会匹配。
如果你想格外小心,如果$names
可以包含一些对正则表达式很重要的东西,例如+
、*
、\
等,你可以添加这个
$matches = preg_grep('/('.implode('|',array_map(function($name)return preg_quote($name,'/');,$names)).')(?1)/', $names_list);
【讨论】:
这匹配benbenclinton
。不确定 OP 是否期望一个术语与两个子字符串完全匹配。
@TimBiegeleisen - 你的也是。 Sandbox
我可以用 ^
和 $
Sandbox 做同样的事情 - 只是说。 :-)【参考方案2】:
您似乎想要匹配两个关键字的精确组合的数组元素。对于正则表达式方法,我们可以尝试取 keyords 向量的叉积,然后生成一个交替。然后,我们可以对您的输入数组使用preg_grep
来查找所有匹配的元素。
$array = array("benclinton", "clintonharry", "harryben", "benwill", "jasonsmith", "smithclinton");
$input = array("ben", "harry", "clinton");
$regex = "";
foreach ($input as $term1)
foreach ($input as $term2)
if ($regex != "") $regex .= "|";
$regex .= $term1.$term2;
$regex = "/^(" . $regex . ")$/";
$matches = preg_grep($regex, $array);
print_r($matches);
Array
(
[0] => benclinton
[1] => clintonharry
[2] => harryben
)
这是上面脚本生成的正则表达式交替:
(benben|benharry|benclinton|harryben|harryharry|harryclinton|clintonben|
clintonharry|clintonclinton)
【讨论】:
谢谢。有什么办法不用for循环?【参考方案3】:不使用 Regex.Do with array_filter
和 strpos
-
过滤器数组与计数大于 1 的第二个数组匹配
Sandbox
<?php
$a = ['benclinton','clintonharry','harryben','benwill','jasonsmith','smithclinton'];
$a2 = ['ben','clinton','harry'];
$res = array_filter($a,function($str="") use($a2)
$r =array_filter($a2,function($a2str) use($str)
return strpos($str,$a2str) !== FALSE;
);
return count($r) > 1;
);
print_r($res);
?>
【讨论】:
以上是关于用于获取仅包含模式列表中单词的字符串的正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章
用于匹配单词的 javascript 正则表达式模式,具有自定义单词边界