例如有一个源字符串:
__aaXXccYYeeXX_ZZkkYYmmXX_ZZnnXXooYYuuXX_ZZvv..
我如何找到所有:aaXX * YY * ZZ
__ aaXX cc YY eeXX_ ZZ kkYYmmXX_ZZnnXXooYYuuXX_ZZvv ..
__ aaXX cc YY eeXX_ZZkkYYmmXX_ ZZ nnXXooYYuuXX_ZZvv ..
__ aaXX cc YY eeXX_ZZkkYYmmXX_ZZnnXXooYYuXX_ ZZ vv ..
__ aaXX ccYYeeXX_ZZkk YY mmXX_ ZZ nnXXooYYuuXX_ZZvv ..
__ aaXX ccYYeeXX_ZZkk YY mmXX_ZZnnXXooYYuuXX_ ZZ vv ..
__ aaXX ccYYeeXX_ZZkkYYmmXX_ZZnnXXoo YY uuXX_ ZZ vv ..
问题是PHP preg不支持(?< = exp)lookbehind断言中的?+ *(可变长度)(仅允许使用固定长度{N})。
因此需要解决方案而不使用具有可变长度的lookbehind断言。
谢谢!
答案 0 :(得分:1)
你需要循环。首先查找__aaXX
,然后查找下一个YY
,然后查看__aaXX
,然后查看第二个YY
等。在正则表达式中,这意味着您首先查找__aaXX(.*?YY){1}
,那么__aaXX(.*?YY){2}
(你能在那里看到一个循环变量吗?)等等,直到模式失败。当您查找ZZ
时,第二部分也是如此。
答案 1 :(得分:1)
此脚本有效:
<?php // test.php 20110311_1200
$data = '__aaXXccYYeeXX_ZZkkYYmmXX_ZZnnXXooYYuuXX_ZZvv..';
$all_matches = array();
$yy_match = true; // Get past first for test condition.
for ($yy_cnt = 1; $yy_match; ++$yy_cnt) {
$yy_match = false; // Assume failure for this yy_cnt.
$zz_match = true; // Get past first for test condition.
for ($zz_cnt = 1; $zz_match; ++$zz_cnt) {
$zz_match = false; // Assume failure for this zz_cnt.
// Assemble new regex with new $yy_cnt and $zz_cnt.
$re = "/ # Match all combinations of XX..YY..ZZ.
(aaXX) # $1: Prefix X.
(?: # Group to find YY[yy_cnt].
(?:(?!YY).)* # Zero or more non-YY.
(YY) # $2: next YY.
){{$yy_cnt}} # yy_cnt.
(?: # Group to find ZZ[zz_cnt].
(?:(?!ZZ).)* # Zero or more non-ZZ.
(ZZ) # $3 next ZZ.
){{$zz_cnt}} # $zz_cnt.
/x";
if (preg_match($re, $data, $matches, PREG_OFFSET_CAPTURE)) {
$zz_match = true;
$yy_match = true;
$all_matches[] = $matches;
printf("Match found. \$yy_cnt = %d, \$zz_cnt = %d\n",
$yy_cnt, $zz_cnt);
}
}
}
print_r($all_matches);
?>
答案 2 :(得分:0)
这种模式怎么样:# aaXX(.*) YY (.*) ZZ .*#
?
从你的突出显示来看,你的结果应该是什么样子并不完全清楚...我添加了空格,因为你在突出显示中有它们,但不清楚你是否会将它们放在源代码中......
修改强>
我想我不明白你想要得到什么,但另一件要看的是preg_match_all,如果你的YY ZZ部分重复......就像#_aaXX((.*?)YY(.*?)ZZ)+#
那样。