Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate string # followed by digits but # increases after every occurance

Tags:

regex

pcre

I have a string looks like this

#123##1234###2356####69

It starts with # and followed by any digits, every time the # appears, the number of # increases, first time 1, second time 2, etc.

It's similar to this regex, but since I don't know how long this pattern goes, so it's not very useful.

^#\d+##\d+###\d+$

I'm using PCRE regex engine, it allows recursion (?R) and conditions (?(1)...) etc.

Is there a regex to validate this pattern?

Valid

  • #123
  • #12##235
  • #1234##12###368
  • #1234##12###368####22235#####723356

Invalid

  • ##123
  • #123###456
  • #123##456##789

I tried ^(?(1)(?|(#\1)|(#))\d+)+$ but it doesn't seem to work at all

like image 901
Hao Wu Avatar asked Mar 12 '21 08:03

Hao Wu


2 Answers

You can do this using PCRE conditional sub-pattern matching:

^(?:((?(1)\1)#)\d+)++$

RegEx Demo

RegEx Details:

  • ^: Start
  • (?:: Start non-capture group
    • (: Start capture group #1
      • (?(1)\1): if/then/else directive that means match back-reference \1 only if 1st capture group is available otherwise match null
      • #: Match an additional #
    • ): End capture group #1
    • \d+: Match 1+ digits
  • )++: End non-capture group. Match 1+ of this non-capture group.
  • $: End
like image 177
anubhava Avatar answered Sep 28 '22 03:09

anubhava


One option could be optionally matching a backreference to group 1 inside group 1 using a possessive quantifier \1?+# adding # on every iteration.

^(?:(\1?+#)\d+)++$
  • ^ Start of string
  • (?: Non capture group
    • (\1?+#)\d+ Capture group 1, match an optional possessive backreference to what is already captured in group 1 and add matching a # followed by 1+ digits
  • )++ Close the non capture group and repeat 1+ times possessively
  • $ End of string

Regex demo

like image 25
The fourth bird Avatar answered Sep 28 '22 01:09

The fourth bird