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))*\)$
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