2016-10-04 92 views
4

基本上,我需要组合\k\g匹配与前一组匹配的字符数量相同

下面是一个例子:

我具有在"123045 ; 67089"形式的字符串。只有在数字结尾的同一位置上两个数字都有重复数字时,我才必须匹配。在这种情况下,123045中的0与数字的末尾相距两个位置,67089中的0也是如此。


的问题是,如果我使用反向引用,数字的整个剩余部分必须匹配(又名4589):

^\d*(\d)(\d*) ; \d*\1\2$ 

如果我使用模式的重新执行,我不得不放弃剩余字符的特定数目(在这种情况下 - 2):

^\d*(\d)(\d{2}) ; \d*\1\g<2>$ 

是的,它必须在一个单一的正则表达式中。

+0

只是一个非常快速的出手,不知道是否Ruby支持PCRE完全,不充分的测试:https://regex101.com/r/u0ZBdR/3 –

+1

@SebastianProske:红宝石正则表达式在Onigmo上运行,而不是PCRE。它通过'\ g '符号来支持递归。使用[Rubular](http://rubular.com)来测试Ruby正则表达式模式。 –

+0

@SebastianProske,这很聪明,我应该想到类似的东西。即使它不处理无效输入,但可以调整。发布这个答案(只需用'\ g <2>'替换'(?2)')。 – ndn

回答

3

你在这里面临的是一个平衡的问题。您可以使用递归来解决它,我的做法是:

^\d*(\d)(?:(\d(?:(\s*;\s*\d*\1)|\g<2>)\d)|\g<3>)$ 

这将需要\s*;\s*\d*\1为数字的两个平衡组之间的内容。为了避免递归,这个内容必须只匹配一次(以避免像12212;1;13这样的匹配)。作为交替的这种内容的递归是对于每一个数字的最后一位数字加倍的情况。

你可以找到一些测试用例here