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.
"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
You can verify the pattern by matching the string with the following regular expression.
^\((?:\(\d+\.\d(?: \d+)?\)(?: |(?=\)$)))+\)$
The regular expression can be broken down as follows.
^ # match beginning of string
\( # match '('
(?: # begin non-capture group
\( # match '('
\d+\.\d # match 1+ digits, '.', 1 digit
(?: \d+)? # optionally ('?') match a space then 1+ digits
\( # match ')'
(?: # begin non-capture group
[ ] # match a space
| # or
(?=\)$) # positive lookahead asserts next char is ')' at end of string
) # end non-capture group
)+ # end non-capture group and execute one or more times
\) # match ')'
$ # match end of string