Home > Mobile >  Regex repeated pattern
Regex repeated pattern

Time:02-15

I am tryting the match the following pattern:

((1.0 4) (2.0 5) .... (10.0 8))

The tuple (X N), where X is a floating point number with optional exponent and N is an integer, can be repeated several times.

I tried on this website and I could generate a regex for a fixed number of tuples. For example for 2 tuples I would get

^\(\(([ -]?(?=\.\d|\d)(?:\d )?(?:\.?\d*))(?:[eE]([ -]?\d ))?\s[0-9] \)\s\(([ -]?(?=\.\d|\d)(?:\d )?(?:\.?\d*))(?:[eE]([ -]?\d ))?\s[0-9] \)\)$

How can I modify the pattern so that the number of tuples is arbitrary? I think I will have to use some kind of grouping, but regex is quite new for me.

CodePudding user response:

You may use the following pattern:

^\(\(\d (?:\.\d )? \d \)(?:\s*\(\d (?:\.\d )? \d \))*\)$

Demo

This pattern matches:

^
\(                             (
\(\d (?:\.\d )? \d \)          a leading tuple
(?:\s*\(\d (?:\.\d )? \d \))*  space, more tuples
\)                             )
$

CodePudding user response:

"The tuple (X N), where X is a floating point number with optional exponent and N is an integer, can be repeated several times."

To make sure you have 1 tuples (with optional exponents), you can use:

^\(\([- ]?\d*\.\d ([eE][- ]?\d )?\s\d \)(?:\s\([- ]?\d*\.\d ([eE][- ]?\d )?\s\d \))*\)$

See an online demo


  • ^ - Start-line anchor;
  • \(\( - Two literal opening paranthesis;
  • [- ]?\d*\.\d ([eE][- ]?\d )? - To match your floating point number with optional exponent we match: An optional hypen or plus sign followed by 0 digits and a literal dot with 1 digits. After that is an optional capture group to match the exponent with a letter 'e', an optional hyphen or plus and 1 digits;
  • \s\d \) - To finish the tuple the pattern matches: A single whitespace character and 1 digits to match the integer part of the tuple before a closing paranthesis;
  • (?:\s.....)* - The trick in the following is that we use a non-capture group to match a single whitespace char and the pattern we used for our tuple. When closing this non-capture group match it 0 times to allow for any number of tuples;
  • \)$ - Finish the pattern with a literal closing paranthesis and the end-line anchor.

Or if available, catch the 1st tuple in a capture group and repeat that exact pattern with a backreference:

^\((\([- ]?\d*\.\d ([eE][- ]?\d )?\h\d \))(?:\h(?1))*\)$

See an online demo

CodePudding user response:

You didn't specify regex flavor but I am assuming PHP/PCRE.

This regex with a recursion should work for you:

^\((\(\d \.\d \h\d \))(?:\h (?1))*\)$

RexEx Demo

RegEx Details:

  • ^: Start
  • \(: Match a (
  • (: Start 1st capture group
    • \(:
    • \d \.\d : Match a floating point number
    • \h: Match a white space
    • \d : Match 1 digits
    • \): Match a )
  • ): End 1st capture group
  • (?:: Start non-capture group
    • \h : Match 1 whitespaces
    • (?1): Recurse 1st capture group
  • )*: End non-capture group. Repeat this group 0 or more times
  • \): Match a )
  • $; End
  • Related