如何使用起始词和结束词数组PHP查找字符串中的所有子字符串



我在过去的4个小时里一直在想如何。。。我现在得请求你的帮助。

我试图从文本中提取与starting_words_array和ending_words_array匹配的多个子字符串。

$str = "Do you see that ? Indeed, I can see that, as well as this." ;
$starting_words_array = array('do','I');
$ending_words_array = array('?',',');

预期输出:数组([0]=>'你看到了吗?'[1]=>'我能看到,'(

我设法编写了第一个函数,可以找到与两个数组项之一匹配的第一个子字符串。但我不知道如何循环它,以获得符合我要求的所有子字符串。

function SearchString($str, $starting_words_array, $ending_words_array ) {
forEach($starting_words_array as $test) {
$pos = strpos($str, $test);
if ($pos===false) continue;
$found = [];
forEach($ending_words_array  as $test2) {
$posStart = $pos+strlen($test);
$pos2 = strpos($str, $test2, $posStart);
$found[] = ($pos2!==false) ? $pos2 : INF;
}
$min = min($found);
if ($min !== INF)
return substr($str,$pos,$min-$pos) .$str[$min];
}
return '';
}

你们知道如何做到这一点吗?

我的解决方案使用preg_match。但是,起始字符串和结束字符串必须使用preg_quote进行转义。否则,解决方案将是错误的。

function searchString($str, $starting_words_array, $ending_words_array ) {
$resArr = [];
forEach($starting_words_array as $i => $start) {
$end = $ending_words_array[$i] ?? "";
$regEx = '~'.preg_quote($start,"~").".*".preg_quote($end,"~").'~iu';
if(preg_match_all($regEx,$str,$match)){
$resArr[] = $match[0];
}
}
return $resArr;
}

结果是提问者所期望的。

如果表达式可以出现多次,则还必须使用preg_match_all。正则表达式必须修改。

function searchString($str, $starting_words_array, $ending_words_array ) {
$resArr = [];
forEach($starting_words_array as $i => $start) {
$end = $ending_words_array[$i] ?? "";
$regEx = '~'.preg_quote($start,"~").".*?".preg_quote($end,"~").'~iu';
if(preg_match_all($regEx,$str,$match)){
$resArr = array_merge($resArr,$match[0]);
}
}
return $resArr;
}

第二种变体的结果:

array (
0 => "Do you see that ?",
1 => "Indeed,",
2 => "I can see that,",
)

我肯定会使用regex和preg_match_all()。我不会在这里给你一个完整的工作代码示例,但我会概述必要的步骤。

首先,从开始-结束对构建一个regex,如下所示:

$parts = array_map(
function($start, $end) {
return $start . '.+' . $end;
},
$starting_words_array,
$ending_words_array
);
$regex = '/' . join('|', $parts) . '/i';

/i部分表示不区分大小写的搜索。像?这样的一些字符在regex中有特殊的用途,所以您需要扩展上面的函数才能正确地转义它。你可以在这里测试你的最终正则表达式

然后使用preg_match_all()提取子字符串:

preg_match_all($regex, $str, $matches); // $matches is passed by reference, no need to declare it first
print_r($matches);

你的$matches数组的确切结构与你要求的略有不同,但你可以从中提取你想要的数据

Benni的答案是最好的方法,但如果您想解决这些问题,请指出代码中的问题:

  1. strpos不区分大小写,也可以查找单词的一部分,因此您需要将$starting_words_array = array('do','I');更改为$starting_words_array = array('Do','I ');
  2. 在查找子字符串时,您使用return退出函数,以便查找任何其他子字符串。为了解决这个问题,您可以在函数的开头定义$res = [];,用$res[] = substr($str,$pos,...替换return substr($str,$pos,...,并在末尾返回$res变量

您可以在3v4l中看到示例-在该示例中,您可以获得想要的输出

最新更新