1

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.

1
  • You question needs greater specificity. At first (based largely on your example) I assumed that X is the string representation of a non-negative float with one digit to the right of the decimal point and N was the optional exponent. Now that I look at the regex you give I see neither of those assumptions were correct. At minimum you need to expand your example to include negative floats, exponents and so on. Also, make it a valid Javascript object (in part, no '....') so that readers can test code against your example and variants therefore, including invalid strings. Commented Feb 15, 2022 at 19:40

3 Answers 3

3

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
\)                             )
$
Sign up to request clarification or add additional context in comments.

2 Comments

Wow, that was fast! Almost there. The second number must bit an integer. Your regex also matches ((1.0 2) (2.0 4) (3.0 8.0))
It wasn't clear that the second number in the tuple were always an integer. I have updated my answer.
2

"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

Comments

1

You can verify the pattern by matching the string with the following regular expression.

^\((?:\(\d+\.\d(?: \d+)?\)(?: |(?=\)$)))+\)$

Demo

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.