使用反向引用作为重复计数的正则表达式

10

有没有一种方法可以构建一个正则表达式,实现以下功能:

匹配整数作为组1,然后匹配\1个整数。

很不幸,这个(\d+)(\s+\d+){\1}是不被允许的,但我认为它描述了我正在尝试实现的内容。


4
我正在使用的语言是什么? - Amit Joki
7
通常不支持这种做法。可能可以使用“代码呼出”(code callout)实现,但这是一些人不喜欢的功能(当Perl正则表达式文档说“一点魔术”时,你应该担心)。你也可以编写两个模式:获取数字、解析它并构建第二个模式(或运行\s+\d+ n次)。 - Kobi
2
@Kobi 这可能是一个答案。 - hek2mgl
1
重要的是你使用什么编程语言和正则表达式引擎。理论上,可以这样实现:$text =~ m/(\d+)([\s\d]+)(\g{-1})/mg 或者 m/(\d+)([\s\d]+)(\1)/mg - 这是在 Perl 中实现的。在 PHP 中,代码看起来像这样:preg_match('/(\d+)([\s\d]+)(\1)/m', $subject)。 - rheese
这里是一个例子:https://jsfiddle.net/rx2qvrm2/ - rheese
@rheese 我对能够用任何语言实现的解决方案感兴趣。我没有举例,这是我的失误:对于字符串“3 7 6 5 4 3 2 1”,我想匹配数字3和接下来的3个数字,即“3 7 6 5”。您的答案匹配了3,然后是所有数字和另一个3。 - Noxitu
2个回答

2
你可以像这样做:

您可以像这样做:

var numbers = "3 7 6 5 4 3 2 1"; // list of numbers
var iter = numbers.split(" ")[0] // get first number
numbers = numbers.substr(iter.length+1) // chop off first number, and the space that follows it you can comment
var rex = new RegExp("(?:\\d(?: |$)){" + iter + "}","") // create regex
alert((numbers.match(rex)||[]).join("\n")) // a sample alert that joins the array to a string with an element on each line

或者,如果你想要第一个数字来定义在同一数组中出现的次数,只需进行一些更改即可实现。

var numbers = "3 7 6 5 4 3 2 1"; // list of numbers
var iter = numbers.split(" ")[0] // get first number
var rex = new RegExp("(?:\\d(?: |$)){" + (+iter+1) + "}","") // create regex
alert((numbers.match(rex)||[]).join("\n")) // a sample alert that joins the array to a string with an element on each line

0
感谢@Kobi的建议使用代码调用。确实可以使用最后一个反向引用构建动态长度匹配。代码应该类似于这样:
$s = '3 4 5 6 7 8 9 10';
$s =~ /(\d+)\s+((??{"(\\s*\\d+){$^N}"}))/;
print "$1\n$2\n"

打印

3
4 5 6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接