我有以下代码:
$wordsArray = ...
foreach ( $wordsArray as $word )
if ( strpos( $string, $word ) !== FALSE ) {
echo "Word found! Handle this a certain way" }
}
}
不幸的是,有这么大的单词数组(可能接近100),循环太慢了,特别是当我向这个函数传递数千个字符串,并运行这个foreach循环数千次。我如何加快这个过程,或重构我的代码,我不需要循环我的单词数组,而是利用字符串本身并检查它是否在我的数组中找到它的任何子字符串?我需要让这部分代码更有效率。
此外,更难的是每个字符串都没有空格。相反,请采用以下示例:
传递字符串:“Hereissomerandomsentence”
单词数组:('some','are','the');
由于“some”,我的脚本将返回Word Found,但我想找到一种更快的方法来执行此操作。
答案 0 :(得分:2)
不管你喜欢与否,都会涉及到一些循环,但是当你切换到正则表达式时,可能会进行一些优化:
$re = '/(?:' . join('|', array_map(function($word) {
return preg_quote($word, '/');
}, $wordsArray)) . ')/';
if (preg_match_all($re, $string, $matches)) {
// hurray!
print_r($matches[0]);
}
答案 1 :(得分:1)
容易但也不容易。以下是一些使用preg_match_all
和简单正则表达式作为示例的代码:
// Set the string.
$string = 'Hereissomerandomsentence';
// Set the words array.
$wordsArray = array('some', 'are', 'the');
// Set the regex pattern.
$regex_pattern = '/(?:' . implode('|', $wordsArray) . ')/i';
// Run a regex to get the value between the link tags.
preg_match_all($regex_pattern, $string, $matches);
// Return the results.
echo '<pre>';
print_r($matches);
echo '</pre>';
以下是结果:
Array
(
[0] => Array
(
[0] => some
)
)
但是当我说这不容易时,缺少空格可能会导致then
与the
匹配等等。请记住,计算机无法读取。这都是模式逻辑。因此,如果我将then
和are
添加到示例字符串中,如下所示:
// Set the string.
$string = 'Hereissomerandomsentencethenhereweare';
结果反映了the
中的then
被提取:
Array
(
[0] => Array
(
[0] => some
[1] => the
[2] => are
)
)
编辑:原始海报在评论中提出了一个公平但复杂的问题:
如果我只想要一个单词前面有另一个单词,该怎么办?对于 例如,使用相同的测试字符串,您如何更改正则表达式 仅在
some
之前包含is
,the
之前包含then
are
和are
前面有&#39;我们&#39;?所以对你的例子来说 输出只会是某些&#39;和$string = 'Hereissomerandomsentencethenhereweare'; // Set the regex pattern. $regex_pattern = '/(?<=is)some|(?<=then)the|(?<=we)are/i'; // Run a regex to get the value between the link tags. preg_match_all($regex_pattern, $string, $matches); // Return the results. echo '<pre>'; print_r($matches); echo '</pre>';
。
您要求做的事情很复杂,但使用“Lookarounds”as explained on this site可行:
以下是使用上述代码的示例:
Array
(
[0] => Array
(
[0] => some
[1] => are
)
)
结果将如您所愿:
/(?<=is)some|(?<=then)the|(?<=we)are/i
这是对正则表达式/
的解释:
|
)只是分隔符。OR
字符只是条件之间的OR
。(?<=is)some
条件之间存在的是模式。现在让我们以第一个(?<=[word in here])
为例。
is
是一个“Lookbehind”,意思是:只有在此处带有单词的前面,才会捕获后面的单词。在这种情况下,some
。some
。is
,则只匹配the
。然后then
仅在前面有are
。然后we
仅在前面加{{1}}。现在知道这里有一个模式可能会创建一个多维数组,可以设置单词的逻辑,只有在前面有另一个单词时才能检查。然后循环,以创建一堆正则表达式。但这是一项艰巨的任务。
但至少现在你知道这个任务的正则表达式的基础知识了!
答案 2 :(得分:1)
使用这些想法,您可以减少所需的比较次数。通过减小潜在解决方案集的大小,您可以加快匹配速度。
为了使这些减少技术显示其价值,潜在匹配的数组将需要很大。也就是说,您节省的处理时间需要超过削减不太可能的匹配所花费的处理时间。
在提供的示例字符串中,字母表的使用方式如下: a2 b c 1 d 1 e 11 F G 3 我1 Ĵ ķ 升 m 2 n 4 o 2 p q 4 3 t 2 ü v w 1 X ÿ ž。
因此,根本没有使用13个字母的26个字母。一半的字母没有出现。此外,e的发生率几乎是其竞争对手的3倍:h,n和r。这意味着根据他们的开始方式消除下属单词可能会减少时间。