4

After googling many days about the issue, finally I am posting this question here and hoping to get it solved by experts here; I am looking for the regex pattern that can match incremental back references. Let me explain:

For number 9422512322, the pattern (\d)\1 will match 22 two times, and I want the pattern (something like (\d)\1+1) that matches 12 (second digit is equal to first digit + 1)

In short the pattern should match all occurrence like 12, 23, 34, 45, 56, etc... There is no replacement, just matches required.

Unihedron
  • 10,902
  • 13
  • 62
  • 72
Gadara
  • 73
  • 4

4 Answers4

6

What about something like this?

/01|12|23|34|45|56|67|78|89/

It isn't sexy but it gets the job done.

Asaph
  • 159,146
  • 25
  • 197
  • 199
  • This regexp won't match "23" in the substring "123" because it first matches "12". The current position of the match operation will be placed after the "2" once it matches "12" and therefore it will not able to see "23". You might be able to get around this problem using [zero-width positive lookahead assertions](http://www.regular-expressions.info/lookaround.html). – Sam Choukri Nov 06 '14 at 23:39
  • @SamChoukri: 2 things: First of all, finding overlapping matches is not an issue with this specific regular expression, but rather an issue with regular expressions in general, regardless of the pattern. Secondly, you can work around it by using the expression in a loop where you find the next match using a start position of the beginning of the previous match plus 1. – Asaph Nov 07 '14 at 00:13
1

You can use this regex:

(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9))+.

This will match:

  • Any 0s which are followed by 1s, or
  • Any 1s which are followed by 2s, or
  • Any 2s which are followed by 3s, ...

Multiple times +, then match the corresponding character ..

Here is a regex demo, and the match is:

12345555567877785
Unihedron
  • 10,902
  • 13
  • 62
  • 72
0

You can run code within Perl regular expressions that can
control the regex execution flow. But, this is not likely
to be implemented anywhere else to this degree.

PCRE has some program variable interaction, but not like Perl.
(Note - to do overlap finds, replace the second ( \d ) with (?=( \d ))
then change print statement to print "Overlap Found $1$3\n";

If you use Perl, you can do all kinds of math-character relationships that can't be
done with brute force permutations.

- Good luck!

Perl example:

use strict;
use warnings;

my $dig2;
while ( "9342251232288 6709090156" =~
          /
               (
                    ( \d )
                    (?{ $dig2 = $^N + 1 })
                    ( \d )
                    (?(?{
                         $dig2 != $^N
                      })
                         (?!)
                    )
               )
          /xg )
{
    print "Found  $1\n";
}

Output:

Found  34
Found  12
Found  67
Found  01
Found  56
0

Here is one way to do it in Perl, using positive lookahead assertions:

#!/usr/bin/env perl

use strict;
use warnings;

my $number = "9422512322";

my @matches = $number =~ /(0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9))/g;

# We have only matched the first digit of each pair of digits.
# Add "1" to the first digit to generate the complete pair.
foreach my $first (@matches) {
  my $pair = $first . ($first + 1);
  print "Found: $pair\n";
}

Output:

Found: 12
Found: 23
Sam Choukri
  • 1,874
  • 11
  • 17