简体   繁体   中英

Regex match valid Phone Number

I'm quite new to regex, and not sure what I'm doing wrong exactly.

I'm looking for a regex that match the following number format:

Matching requirements:

  1. Must start with either 0 or 3
  2. Must be between 7 to 11 digits
  3. Must not allow ascending digits. eg 0123456789, 01234567
  4. Must not allow repeated digits. eg 011111111, 3333333333, 0000000000

This is what I came up with:

^(?=(^[0,3]{1}))(?!.*(\d)\1{3,})(?!^(?:0(?=1|$))?(?:1(?=2|$))?(?:2(?=3|$))?(?:3(?=4|$))?(?:4(?=5|$))?(?:5(?=6|$))?(?:6(?=7|$))?(?:7(?=8|$))?(?:8(?=9|$))?9?$).{7,11}$

The above regex fails the No. (4) condition. Not sure why though.

Any help would be appreciated.

Thanks

A solution for a JS flavor of PCRE would be

/^[03](?!123456(7(8(9|$)|$)|$))(?!(?<d>.)\\k<d>+$)[0-9]{6,10}$/

Explanations

  1. ^[03] starts at the beginning of the string, then reads either 0 or 3
  2. (?!123456(7(8(9|$)|$)|$)) makes sure that, after this first char, there is no sequence (if a sequence can be read, then the negative lookahead fails
  3. (?!(?<d>.)\\k<d>+$) is another negative lookahead : it ensures that the first char read (flagged d ) is not repeated again and again until end of string
  4. [0-9]{6,10}$/ finally reads 6 to 10 digits (first one already read)

A few tests:

  • "0123456789: No match"
  • "01234567: No match"
  • "01234568: No match"
  • "011111111: No match"
  • "33333333: No match"
  • "333333233 is valid"
  • "042157891023 is valid"
  • "019856: No match"
  • "0123451245 is valid"

A few notes about the pattern that you tried

  • You can omit the {1} and the comma in [0,3]
  • In the lookahead (?!.*(\\d)\\1{3,}) the (\\d) is the second capturing group because this (?=(^[0,3]{1})) contains the first capturing group so it should be \\2 instead of \\1
  • In the lookahead, you can omit the comma in {3,}
  • In the match itself you use .{7,11} where the dot would match any character except a newline. You could use \\d instead to match only digits

You pattern might look like

^(?=(^[03]))(?!.*(\d)\2{3})(?!^(?:0(?=1|$))?(?:1(?=2|$))?(?:2(?=3|$))?(?:3(?=4|$))?(?:4(?=5|$))?(?:5(?=6|$))?(?:6(?=7|$))?(?:7(?=8|$))?(?:8(?=9|$))?9?$)\d{7,11}$

Regex demo

Or leaving out the first lookahead and move that to the match, changing the quantifier to \\d{6,10} and repeating capture group \\1 instead of \\2

^(?!.*(\d)\1{3})(?!(?:0(?=1|$))?(?:1(?=2|$))?(?:2(?=3|$))?(?:3(?=4|$))?(?:4(?=5|$))?(?:5(?=6|$))?(?:6(?=7|$))?(?:7(?=8|$))?(?:8(?=9|$))?9?$)[03]\d{6,10}$

Regex demo

Edit

Based on the comments, the string not having 4 ascending digits:

^(?!.*(\d)\1{3})[03](?!\d*(?:0123|1234|2345|3456|4567|5678|6789))\d{6,10}$

Regex demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM