我很抱歉这个糟糕的头衔,但这是一个非常通用的问题
我必须匹配这种模式
;AAAAAAA(BBBBBB,CCCCC,DDDDDD)
“x和y之间的所有字符”是每次都会导致我的问题
:(
我正在使用PHP,我必须匹配所有出现的这种模式(preg_match_all),遗憾的是,它可以在多行上
提前谢谢!
答案 0 :(得分:3)
我建议你不要使用不合理的量词,而是将所有重复与其分隔符互斥。这是什么意思?例如,这意味着A
可以是除(
之外的任何字符。给这个正则表达式:
;([^(]*)[(]([^,]*),([^,]*),([^)]*)[)]
甚至不需要最后[)]
。
PHP代码将如下所示:
preg_match_all('/;([^(]*)[(]([^,]*),([^,]*),([^)]*)[)]/', $input, $matches);
$fullMatches = $matches[0];
$arrayOfAs = $matches[1];
$arrayOfBs = $matches[2];
$arrayOfCs = $matches[3];
$arrayOfDs = $matches[4];
正如评论所示,我的逃避技术是一个品味问题。这个正则表达式当然等于:
;([^(]*)\(([^,]*),([^,]*),([^)]*)\)
但我认为这看起来比其他变种更不匹配/不平衡。带你去挑选!
最后,对于为什么这种方法比使用ungreedy(懒惰)量词更好的问题。 Here is some good, general reading.基本上,当你使用不合理的量词时,引擎仍然需要回溯。它首先尝试重复一次,然后注意到(
之后不匹配。所以它必须回到重复并消耗另一个角色。但是(
仍然不匹配,所以再次回到重复。然而,通过这种方法,当第一次进行重复时,引擎将尽可能多地消耗。当消耗掉所有非(
个字符时,引擎就能立即匹配以下(
。
答案 1 :(得分:1)
你可以使用类似这样的代码:
preg_match_all('/;(.*?)\((.*?),(.*?),(.*?)\)/s',$text,$matches);
在ideone.com上查看。
基本上,你可以使用.*?
(问号是不合适的),确保转义括号,你可能需要s
修饰符让它在多行上运行。
变量将在数组中:$matches