Regular expression to match 12345

蹲街弑〆低调 提交于 2019-12-21 15:09:26

问题


Is there a regex to match a string of increasing contiguous numbers, e.g. 123, 56789, etc? I don't think it can be in regex but worth checking with folks here.


回答1:


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

Result: http://rubular.com/r/JfJJ6ntEQG




回答2:


^(1|^)((2|^)((3|^)((4|^)((5|^)((6|^)((7|^)((8|^)((9|^))?)?)?)?)?)?)?)?$

Python demonstration:

>>> import re
>>> good  = ['1', '12', '123', '23', '3', '4', '45', '456', '56', '6', '7', '78', '789', '89', '9', '123456789']
>>> bad   = ['a', '11', '13', '1345', '2459', '321', '641', '1 2', '222233334444']
>>> tests = good + bad
>>>
>>> regex = '^(1|^)((2|^)((3|^)((4|^)((5|^)((6|^)((7|^)((8|^)((9|^))?)?)?)?)?)?)?)?$'
>>> for test in tests:
...   print '%s: %s' % (re.match(regex, test) and 'Passed' or 'Failed', test)
... 
Passed: 1
Passed: 12
Passed: 123
Passed: 23
Passed: 3
Passed: 4
Passed: 45
Passed: 456
Passed: 56
Passed: 6
Passed: 7
Passed: 78
Passed: 789
Passed: 89
Passed: 9
Passed: 123456789
Failed: a
Failed: 11
Failed: 13
Failed: 1345
Failed: 2459
Failed: 321
Failed: 641
Failed: 1 2
Failed: 222233334444



回答3:


Is there a regex to match a string of increasing contiguous numbers, e.g. 123, 56789, etc?

But of course there is, since the answer to all questions beginning, “Is there a (Perl) regex to match…?” is always “Why, certainly there is!” The operative question is always, “What is the Perl regex to match…?” ☺

Short Answer

That Perl regular expression is this one:

m{
  ^ (
      ( \d )
      (?(?= ( \d )) | $)
      (?(?{ ord $3 == 1 + ord $2 }) (?1) | $)
    ) $
}x

If works by having two different (?(COND)THEN|ELSE) conditional groups, with recursion on group 1 as the THEN clause of the second of those. That’s what (?1) does.

Nifty, eh?

Recursive patterns like these are awesomely cool and incredibly powerful; it’s up to you to use this power in the service of good, not evil. ☺

I use a lightly less clever form of it in the program given below. I’ll leave the other one there where it started just so you can see that in Perl There’s More Than One Way To Do It.

Full Demo Program

Notice that this works no matter what the string of Unicode digits, including non-ASCII (welcome to the Brave New Millennium) and even way up in the Astral Plane where languages stuck on UCS-2, or sometimes even UTF-16, cannot even think about.

This output:

Yes:       3456
 No:         43
Yes:        567
 No:       1245
 No:        568
 No:        987
Yes:         12
Yes:      12345
 No:         24
 No:      13456
 No:   12354678
Yes:   12345678
 No:       ١٣٠٢
Yes:       ٤٥٦٧
 No:        २१३
Yes:       ४५६७
Yes:         ८९
 No:        ১১২
Yes:       ৩৪৫৬
 No:       ৭৮৯৮
Yes:         ௮௯
 No:         ௮௮
 No:       ๖๗๗๘
Yes:        ๖๗๘
 No:    ༣༤༢༥༧༦༨
 No:      01132
Yes:        234
Yes:         89
Yes:       𝟐𝟑𝟒𝟓
 No:       𝟓𝟒𝟑𝟐
 No:       𝟙𝟚𝟚𝟛
Yes:       𝟛𝟜𝟝𝟞
Yes:  𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵
Yes:         𝟶𝟷
 No:      𝟸𝟹𝟺𝟼𝟻
Yes:    𝟹𝟺𝟻𝟼𝟽𝟾𝟿

Is produced by this program:

#!/usr/bin/env perl   
use 5.10.0;
use utf8;
use strict;
use autodie;
use warnings  qw<  FATAL all     >;
use open      qw< :std  :utf8    >;
use charnames qw< :full          >;

# to iterate is human…
my @numbers = (
        3456,
          43,
         567,
        1245,
         568,
         987,
          12,
       12345,
          24,
       13456,
    12354678,
    12345678,
    hard_stuff(),
);   
my $ascending_rx = qr{
   ^ (  # works for *ANY* script!
        ( \p{Decimal_Number} ) 
        (?= $ | (??{ chr(1+ord($2)) }) )
        (?: (?1) | $ ) # …to recurse, divine!
    ) $
}x;

for my $n (@numbers) {
    printf "%s: %10s\n",
        ($n =~ $ascending_rx) ? "Yes" : " No",
        $n;
}

sub hard_stuff {   
    ( "\N{ARABIC-INDIC DIGIT ONE}"
    . "\N{ARABIC-INDIC DIGIT THREE}"
    . "\N{ARABIC-INDIC DIGIT ZERO}"
    . "\N{ARABIC-INDIC DIGIT TWO}"
    ),
    ( "\N{ARABIC-INDIC DIGIT FOUR}"
    . "\N{ARABIC-INDIC DIGIT FIVE}"
    . "\N{ARABIC-INDIC DIGIT SIX}"
    . "\N{ARABIC-INDIC DIGIT SEVEN}"
    ),
    ( "\N{DEVANAGARI DIGIT TWO}"
    . "\N{DEVANAGARI DIGIT ONE}"
    . "\N{DEVANAGARI DIGIT THREE}"
    ),
    ( "\N{DEVANAGARI DIGIT FOUR}"
    . "\N{DEVANAGARI DIGIT FIVE}"
    . "\N{DEVANAGARI DIGIT SIX}"
    . "\N{DEVANAGARI DIGIT SEVEN}"
    ),
    ( "\N{DEVANAGARI DIGIT EIGHT}"
    . "\N{DEVANAGARI DIGIT NINE}"
    ),
    ( "\N{BENGALI DIGIT ONE}"
    . "\N{BENGALI DIGIT ONE}"
    . "\N{BENGALI DIGIT TWO}"
    ),
    ( "\N{BENGALI DIGIT THREE}"
    . "\N{BENGALI DIGIT FOUR}"
    . "\N{BENGALI DIGIT FIVE}"
    . "\N{BENGALI DIGIT SIX}"
    ),
    ( "\N{BENGALI DIGIT SEVEN}"
    . "\N{BENGALI DIGIT EIGHT}"
    . "\N{BENGALI DIGIT NINE}"
    . "\N{BENGALI DIGIT EIGHT}"
    ),
    ( "\N{TAMIL DIGIT EIGHT}"
    . "\N{TAMIL DIGIT NINE}"
    ),
    ( "\N{TAMIL DIGIT EIGHT}"
    . "\N{TAMIL DIGIT EIGHT}"
    ),
    ( "\N{THAI DIGIT SIX}"
    . "\N{THAI DIGIT SEVEN}"
    . "\N{THAI DIGIT SEVEN}"
    . "\N{THAI DIGIT EIGHT}"
    ),
    ( "\N{THAI DIGIT SIX}"
    . "\N{THAI DIGIT SEVEN}"
    . "\N{THAI DIGIT EIGHT}"
    ),
    ( "\N{TIBETAN DIGIT THREE}"
    . "\N{TIBETAN DIGIT FOUR}"
    . "\N{TIBETAN DIGIT TWO}"
    . "\N{TIBETAN DIGIT FIVE}"
    . "\N{TIBETAN DIGIT SEVEN}"
    . "\N{TIBETAN DIGIT SIX}"
    . "\N{TIBETAN DIGIT EIGHT}"
    ),
    ( "\N{FULLWIDTH DIGIT ZERO}"
    . "\N{FULLWIDTH DIGIT ONE}"
    . "\N{FULLWIDTH DIGIT ONE}"
    . "\N{FULLWIDTH DIGIT THREE}"
    . "\N{FULLWIDTH DIGIT TWO}"
    ),
    ( "\N{FULLWIDTH DIGIT TWO}"
    . "\N{FULLWIDTH DIGIT THREE}"
    . "\N{FULLWIDTH DIGIT FOUR}"
    ),
    ( "\N{FULLWIDTH DIGIT EIGHT}"
    . "\N{FULLWIDTH DIGIT NINE}"
    ),
    #############################################
    #   Who's afraid of the astral planes?
    #   Try THIS, all you prisoners of UTF-16!
    #############################################
    ( "\N{MATHEMATICAL BOLD DIGIT TWO}"
    . "\N{MATHEMATICAL BOLD DIGIT THREE}"
    . "\N{MATHEMATICAL BOLD DIGIT FOUR}"
    . "\N{MATHEMATICAL BOLD DIGIT FIVE}"
    ),
    ( "\N{MATHEMATICAL BOLD DIGIT FIVE}"
    . "\N{MATHEMATICAL BOLD DIGIT FOUR}"
    . "\N{MATHEMATICAL BOLD DIGIT THREE}"
    . "\N{MATHEMATICAL BOLD DIGIT TWO}"
    ),
    ( "\N{MATHEMATICAL DOUBLE-STRUCK DIGIT ONE}"
    . "\N{MATHEMATICAL DOUBLE-STRUCK DIGIT TWO}"
    . "\N{MATHEMATICAL DOUBLE-STRUCK DIGIT TWO}"
    . "\N{MATHEMATICAL DOUBLE-STRUCK DIGIT THREE}"
    ),
    ( "\N{MATHEMATICAL DOUBLE-STRUCK DIGIT THREE}"
    . "\N{MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR}"
    . "\N{MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE}"
    . "\N{MATHEMATICAL DOUBLE-STRUCK DIGIT SIX}"
    ),
    ( "\N{MATHEMATICAL SANS-SERIF BOLD DIGIT ONE}"
    . "\N{MATHEMATICAL SANS-SERIF BOLD DIGIT TWO}"
    . "\N{MATHEMATICAL SANS-SERIF BOLD DIGIT THREE}"
    . "\N{MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR}"
    . "\N{MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE}"
    . "\N{MATHEMATICAL SANS-SERIF BOLD DIGIT SIX}"
    . "\N{MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN}"
    . "\N{MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT}"
    . "\N{MATHEMATICAL SANS-SERIF BOLD DIGIT NINE}"
    ),
    ( "\N{MATHEMATICAL MONOSPACE DIGIT ZERO}"
    . "\N{MATHEMATICAL MONOSPACE DIGIT ONE}"
    ),
    ( "\N{MATHEMATICAL MONOSPACE DIGIT TWO}"
    . "\N{MATHEMATICAL MONOSPACE DIGIT THREE}"
    . "\N{MATHEMATICAL MONOSPACE DIGIT FOUR}"
    . "\N{MATHEMATICAL MONOSPACE DIGIT SIX}"
    . "\N{MATHEMATICAL MONOSPACE DIGIT FIVE}"
    ),
    ( "\N{MATHEMATICAL MONOSPACE DIGIT THREE}"
    . "\N{MATHEMATICAL MONOSPACE DIGIT FOUR}"
    . "\N{MATHEMATICAL MONOSPACE DIGIT FIVE}"
    . "\N{MATHEMATICAL MONOSPACE DIGIT SIX}"
    . "\N{MATHEMATICAL MONOSPACE DIGIT SEVEN}"
    . "\N{MATHEMATICAL MONOSPACE DIGIT EIGHT}"
    . "\N{MATHEMATICAL MONOSPACE DIGIT NINE}"
    ),
}

PS: Some say that the reason that There’s More Than One Way To Do It in Perl is to make up for all those other languages in which there are no ways to do it — which is often most of them. ☻




回答4:


In Perl:

my $prev = 0;

while($string =~ s/^\s*(\d+)\s*,\s*(.*)/$2/is) {
    my $new = $1;

    if($new > $prev) { 
        #NUMBERS ARE GETTING LARGER
    } #if 
    else {
        #NUMBER GOT SMALLERS
    }
}


来源:https://stackoverflow.com/questions/4218552/regular-expression-to-match-12345

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!