Noxitu
Noxitu

Reputation: 386

Regex with backreference as repetition count

Is there any way to construct a regex that would work as follows:

Match integer as group 1, then match \1 integers.

This (\d+)(\s+\d+){\1} unfortunetly isn't allowed, but I find it a good description of what i am trying to achive.

Upvotes: 10

Views: 1238

Answers (2)

DaGaMs
DaGaMs

Reputation: 1557

Thanks to @Kobi for the suggestion to use code callouts. It is indeed possible to build a dynamic length match using the last backreference. The code would look something like this:

$s = '3 4 5 6 7 8 9 10';
$s =~ /(\d+)\s+((??{"(\\s*\\d+){$^N}"}))/;
print "$1\n$2\n"

Prints

3
4 5 6

Upvotes: 0

Regular Jo
Regular Jo

Reputation: 5510

You can do something like this

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

Alternatively, if you want the first digit that defines the number of occurrences in the same array, a few changes make it possible

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

Upvotes: 2

Related Questions