用于获取仅包含模式列表中单词的字符串的正则表达式?
Regex for getting strings that contains only the words from the pattern list?
考虑以下数组元素
1.benclinton
2.clintonharry
3.harryben
4.benwill
5.jasonsmith
6.smithclinton
假设模式列表是ben,harry,clinton,那么我应该得到的结果是
1.benclinton
2.clintonharry
3.harryben
所以,基本上结果应该包含仅包含模式列表中的单词的字符串。顺序不重要
此外,每个字符串不会超过两个单词。即 bensmithwill 永远不会出现这种情况。
因为我所有的字符串都在一个数组中,我想在 php 中使用 preg_grep 来做到这一点,但我对为此构建正确的正则表达式感到震惊。
什么正则表达式可以实现这个?除了正则表达式匹配之外,还有其他有效的方法吗?
提前致谢!
您似乎想要匹配两个关键字的精确组合的数组元素。对于正则表达式方法,我们可以尝试取关键字向量的叉积,然后生成一个交替。然后,我们可以对您的输入数组使用 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)
没有 Regex.Do 有 array_filter
和 strpos
- 用计数大于 1 的尊重匹配的第二个数组过滤数组
<?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);
?>
像这样
$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
)
这需要至少两个名称(即使是相同的 2x)匹配。但在这种情况下这是给定的,否则一切都会匹配。
如果您想格外小心,如果 $names
可以包含对正则表达式很重要的内容,例如 +
、*
、\
等,您可以添加这个
$matches = preg_grep('/('.implode('|',array_map(function($name){return preg_quote($name,'/');},$names)).')(?1)/', $names_list);
考虑以下数组元素
1.benclinton
2.clintonharry
3.harryben
4.benwill
5.jasonsmith
6.smithclinton
假设模式列表是ben,harry,clinton,那么我应该得到的结果是
1.benclinton
2.clintonharry
3.harryben
所以,基本上结果应该包含仅包含模式列表中的单词的字符串。顺序不重要
此外,每个字符串不会超过两个单词。即 bensmithwill 永远不会出现这种情况。
因为我所有的字符串都在一个数组中,我想在 php 中使用 preg_grep 来做到这一点,但我对为此构建正确的正则表达式感到震惊。
什么正则表达式可以实现这个?除了正则表达式匹配之外,还有其他有效的方法吗?
提前致谢!
您似乎想要匹配两个关键字的精确组合的数组元素。对于正则表达式方法,我们可以尝试取关键字向量的叉积,然后生成一个交替。然后,我们可以对您的输入数组使用 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)
没有 Regex.Do 有 array_filter
和 strpos
- 用计数大于 1 的尊重匹配的第二个数组过滤数组
<?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);
?>
像这样
$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
)
这需要至少两个名称(即使是相同的 2x)匹配。但在这种情况下这是给定的,否则一切都会匹配。
如果您想格外小心,如果 $names
可以包含对正则表达式很重要的内容,例如 +
、*
、\
等,您可以添加这个
$matches = preg_grep('/('.implode('|',array_map(function($name){return preg_quote($name,'/');},$names)).')(?1)/', $names_list);