php正则重复匹配,php – 用于匹配任何长度的所有重复子串的正则表达式
你的問題是遞歸的…你知道嗎,忘了遞歸! = p它在PHP中不會很好用,如果沒有它,算法也很清楚.
function find_repeating_sequences($s)
{
$res = array();
while ($s) {
$i = 1; $pat = $s[0];
while (false !== strpos($s, $pat, $i)) {
$res[$pat] = 1;
// expand pattern and try again
$pat .= $s[$i++];
}
// move the string forward
$s = substr($s, 1);
}
return array_keys($res);
}
出于興趣,我用PHP寫了Tim’s answer:
function find_repeating_sequences_re($s)
{
$res = array();
preg_match_all('/(?=(.+).*\1)/', $s, $matches);
foreach ($matches[1] as $match) {
$length = strlen($match);
if ($length > 1) {
for ($i = 0; $i < $length; ++$i) {
for ($j = $i; $j < $length; ++$j) {
$res[substr($match, $i, $j - $i + 1)] = 1;
}
}
} else {
$res[$match] = 1;
}
}
return array_keys($res);
}
我讓他們在800字節(jié)隨機(jī)數(shù)據(jù)的小基準(zhǔn)測試中解決它:
$data = base64_encode(openssl_random_pseudo_bytes(600));
每個(gè)代碼運(yùn)行10輪,并測量執(zhí)行時(shí)間.結(jié)果?
Pure PHP - 0.014s (10 runs)
PCRE - 40.86s
當(dāng)你看到24k字節(jié)(或真正高于1k的任何東西)時(shí),它會變得更奇怪:
Pure PHP - 4.565s (10 runs)
PCRE - 0.232s
事實(shí)證明,正則表達(dá)式在1k個(gè)字符之后崩潰,因此$matches數(shù)組為空.這些是我的.ini設(shè)置:
pcre.backtrack_limit => 1000000 => 1000000
pcre.recursion_limit => 100000 => 100000
我不清楚在只有1k個(gè)字符之后是如何命中回溯或遞歸限制的.但即使這些設(shè)置以某種方式“修復(fù)”,結(jié)果仍然很明顯,PCRE似乎不是答案.
我想用C語寫這個(gè)會加速它,但我不確定程度如何.
更新
在hakre’s answer的幫助下,我整理了一個(gè)改進(jìn)版本,在優(yōu)化以下內(nèi)容后,性能提高了約18%:
>刪除外部循環(huán)中的substr()調(diào)用以前進(jìn)字符串指針;這是我之前的遞歸化身遺留下來的.
>將部分結(jié)果用作正緩存,以跳過內(nèi)部循環(huán)內(nèi)的strpos()調(diào)用.
在這里,它的一切榮耀(:
function find_repeating_sequences3($s)
{
$res = array();
$p = 0;
$len = strlen($s);
while ($p != $len) {
$pat = $s[$p]; $i = ++$p;
while ($i != $len) {
if (!isset($res[$pat])) {
if (false === strpos($s, $pat, $i)) {
break;
}
$res[$pat] = 1;
}
// expand pattern and try again
$pat .= $s[$i++];
}
}
return array_keys($res);
}
總結(jié)
以上是生活随笔為你收集整理的php正则重复匹配,php – 用于匹配任何长度的所有重复子串的正则表达式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bccomp在php中什么意思,PHP
- 下一篇: CAP 理论、BASE 理论、FLP 理