Comparing Perl Patterns with Pattern Arithmetic

I want to understand how I can do arithmetic for matched submatrices in perl regex. This is just a sample code, and I want to understand how I can use \1 (the already selected subframe in this case is 7) to match pattern+1 (8)

 my $y = 77668; if($y =~ /(\d)\1(\d)\2\1+1/) #How to increment a previously #matched sub-pattern and form a pattern? { print $y; } 

EDIT

From the answers I see that the arithmetic of the pattern is impossible.

This is what I want to achieve.
I want to create a regex that matches this pattern:

 N-3N-2N-1NNN+1N+2N+3 (N = 3,4,5,6 
+4
source share
2 answers

Its possible using regular expression code blocks:

 my $y = 77668; if($y =~ /(\d)\1(\d)\2(??{$1+1})/ ) { print $y; } 

In this snippet (??{ CODE }) , another regular expression is returned that must match, so this regular expression looks like "8" ($ 1 + 1). As a result, the common regular expression will only match if the 5th digit is larger and the 1st digit is 1. But the disadvantage with the 1st digit is 9, this code block will return “10”, therefore, incorrect behavior is possible, but you said nothing about what should be in this case.

Now about the question N-3N-2N-1NNN+1N+2N+3 , you can match it with this regular expression:

 my $n = 5; if( $y =~ /(??{ ($n-3).($n-2).($n-1).$n.($n+1).($n+2).($n+3) })/ ){ 

Or a more scalable way:

 my $n = 5; if( $y =~ /(??{ $s=''; $s .= $n+$_ foreach(-3..3); $s; })/ ){ 

Again, what should we do if $ n == 2 ?? $ n-3 will be -1. This is not just a number, because it has a sign, so you should think about this case.

Another way. Compare what we have and then check it out.

 if( $y =~ /(\d)(\d)(\d)(\d)(\d)(\d)(\d)/ ) { if( $1 == ($4-3) && $2 == ($4-2) && $3 == ($4-1) && $6 == ($4+1) && $7 == ($4+2) && $7 == ($4+3) ) { #... 

It looks like this litle method is a bit clumsy, but it will take care of everyone (hopefully).

In addition, you can optimize your regular expression, since 7 ascending digits of the strokes are not so often combined, and also get some lulz from xD employees:

 sub check_number { my $i; for($i=1; $i<length($^N); $i++) { last if substr($^N, $i, 1)<=substr($^N, $i-1, 1); } return $i<length($^N) ? "(*FAIL)" : "(*ACCEPT)"; } if( $y =~ /[0123][1234][2345][3456][4567][5678][6789](??{ check_number() })/ ) { 

Or ... Maybe the most convenient way for humans :

 if( $y =~ /0123456|1234567|2345678|3456789/ ) { 

It seems the last option is xD bingo. A good example of not looking for a regex when it's that simple)

+6
source

Of course it is possible. In the end, we are talking about Perl regular expressions. But it will be pretty ugly:

 say "55336"=~m{(\d)\1(\d)\2(\d)(?(?{$1+1==$3})|(*F))}?"match":"fail"; 

or pretty printed:

 say "55336" =~ m{ (\d)\1 (\d)\2 (\d) (? (?{$1+1==$3}) # true-branch: nothing |(*FAIL) ) }x ? "match" : "fail"; 

What does it do? We collect numbers in conventional captures. At the end, we use the if-else pattern:

 (? (CONDITION) TRUE | FALSE ) 

We can embed code in a regular expression with (?{ code }) . The return value of this code can be used as a condition. The verb (*FAIL) (short: (*F) ) causes the match to fail. Use (*PRUNE) if you need a branch, not an entire template.

Embedded code is also great for debugging. However, older pearls cannot use regular expressions inside this regular expression: - (

Thus, we can match many things and check them for validity inside the template itself. However, it would be better to do this outside of the template, for example:

  "string" =~ /regex/ and (conditions) 

Now to your main template N-3N-2N-1NNN+1N+2N+3 (I hope that he correctly disassembled it):

 my $super_regex = qr{ # N -3 N-2 N-1 NN N+1 N+2 N+3 (\d)-3\1-2\1-1\1\1(\d)(\d)(\d) (?(?{$1==$2-1 and $1==$3-2 and $1==$4-3})|(*F)) }x; say "4-34-24-144567" =~ $super_regex ? "match" : "fail"; 

Or did you mean

 my $super_regex = qr{ #N-3 N-2 N-1 NN N+1 N+2 N+3 (\d)(\d)(\d) (\d)\4 (\d)(\d)(\d) (? (?{$1==$4-3 and $2==$4-2 and $3==$4-1 and $5==$4+1 and $6==$4+2 and $7==$4+3})|(*F)) }x; say "123445678" =~ $super_regex ? "match" : "fail"; 

The scary thing is that they even work (with perl 5.12).

We could also generate parts of the template at a time with a construct (??{ code }) - the return value of this code is used as a template:

 my $super_regex = qr{(\d)(??{$1+1})(??{$1+2})}x; say "234"=~$super_regex ? "match":"fail" 

et cetera. However, I think that readability suffers more than that.

If you need more than nine captures, you can use named fragments with

 (?<named>pattern) ... \k<named> 

constructs. Content is also available in the %+ hash, see Perlvar for this.

To delve into the secrets of Perl regular expressions, I recommend reading perlre several times.

+6
source

Source: https://habr.com/ru/post/1445230/


All Articles