regex: match repeated (arbitrary times) pattern, but sort in separate groups

Viewed 158

I'm trying to match (if possible, only) the values of coordinates contained in lines like:

function f is described by the (x,y) couples: 0.000000E+00 0.000000E+00  5.00000     0.500000E-01  1.0000     0.290000      2.0000      1.56000      3.0000      5.47000      4.0000      17.3000      4.50000      31.2000      5.0000      52.6000

The first couple is matched as wished, that is to say in two different groups, by

(?<=\bcouples:\s)(\S+)\s+(\S+)\s+

Then,

    (?<=\bcouples:\s)((\S+)\s+(\S+)\s+)+

matches the whole line, but only splits the last two coordinates in separate groups.

Precision: the number of couples of coordinates is not known, so just adding several times

(\S+)\s+(\S+)\s+

in the end of the regex is not an option.

Thanks for your input!

1 Answers

Use findall():

re.findall(r"(?:\s+([\d\.Ee+-]+)\s+([\d\.Ee+-]+))+?",s)

([\d\.Ee+-]+)\s+([\d\.Ee+-]+) --> two float numbers,
                                  () each of grouped;
 (?:\s+ ... )+? -->  +? there can be more couples, ? means non-greedy matching,
                     (?: the outer group is not interesting;

Edit: You can select the appropriate line:

 if "couples:" in s:
     coords= re.findall(...)

If your text contains more "couples", you can split it. In the following example, we can apply the regex for the 2nd or 3rd, or both part of the splitted string:

s="function f is described by the (x,y) couples: 0.000000E+00 0.000000E+00  5.00000     0.500000E-01 function g is described by the (x,y) couples: 0.1E+00 0.2E+00  9.00000     0.900000E-01"

ls=s.split("couples")
print(ls)
['function f is described by the (x,y) ',
 ': 0.000000E+00 0.000000E+00  5.00000     0.500000E-01 function g is described by the (x,y) ',
 ': 0.1E+00 0.2E+00  9.00000     0.900000E-01']

 re.findall(r"(?:\s+([\d\.Ee+-]+)\s+([\d\.Ee+-]+))+?",ls[1])
 [('0.000000E+00', '0.000000E+00'), ('5.00000', '0.500000E-01')]
Related