3

我很抱歉标题不好,但这是一个非常笼统的问题

我必须匹配这个模式

;AAAAAAA(BBBBBB,CCCCC,DDDDDD)
  • AAAAA = 所有以“;”开头的字符 到“(”(两者;(不包括在内)
  • BBBBB = 从 "(" 到 "," 开始的所有字符(都 (, 不包括在内)
  • CCCCC = 从“,”到“,”的所有字符(都,,不包括在内)
  • DDDDD = 从 "," 到 ")" 开始的所有字符(不包括 ,))

“x 和 y 之间的所有字符”是一个每次都让我丧命的问题

:(

我正在使用 PHP,我必须匹配所有出现的这种模式(preg_match_all),遗憾的是,它也可以在多行上

先感谢您!

4

2 回答 2

3

我建议您不要使用不贪婪的量词,而是使所有重复与其分隔符互斥。这是什么意思?例如,这意味着A可以是除 之外的任何字符(。给出这个正则表达式:

;([^(]*)[(]([^,]*),([^,]*),([^)]*)[)]

最后一个[)]甚至没有必要。

PHP 代码将如下所示:

preg_match_all('/;([^(]*)[(]([^,]*),([^,]*),([^)]*)[)]/', $input, $matches);
$fullMatches = $matches[0];
$arrayOfAs = $matches[1];
$arrayOfBs = $matches[2];
$arrayOfCs = $matches[3];
$arrayOfDs = $matches[4];

正如评论所显示的,我的逃跑技巧是一个品味问题。这个正则表达式当然等于:

;([^(]*)\(([^,]*),([^,]*),([^)]*)\)

但我认为这看起来比其他变体更不匹配/不平衡。任你挑!

最后,对于为什么这种方法比使用不贪婪(惰性)量词更好的问题。这是一些很好的一般性阅读。基本上,当您使用不贪婪的量词时,引擎仍然必须回溯。它首先尝试一次重复,然后注意到(之后不匹配。所以它必须回到重复并消耗另一个角色。但是(仍然不匹配,所以再次回到重复。但是,使用这种方法,引擎将在第一次进入重复时尽可能多地消耗。并且当所有非(字符都被消耗掉时,引擎将能够立即匹配以下内容(

于 2012-11-22T22:05:26.533 回答
1

你可以使用类似这样的代码:

preg_match_all('/;(.*?)\((.*?),(.*?),(.*?)\)/s',$text,$matches);

ideone.com上查看。

基本上,您可以使用.*?(问号不贪心),确保转义括号,并且您可能需要s修饰符使其在多行上工作。

变量将在一个数组中:$matches

于 2012-11-22T22:12:56.707 回答