Jeremyapple
Jeremyapple

Reputation: 263

How to capture a number while matching a regex?

I am able to edit the file using the following code. I am also able to match the regex and replace it. However, while replacing, I want to capture the number in (r\d+ ASSRT\) in the text1_to_search and use the same in replacement1_text.

Right now, I hardcoded it as 749679. How can I do that?

import fileinput, re

filename = 'epivers.h'
text1_to_search = re.compile(r'#define\s+EPI_VERSION_STR\s+"\d+(?:\.\d+)+\s+\(TOB\)\s+\(r\d+ ASSRT\)"')
replacement1_text = '#define EPI_VERSION_STR         "9.130.27.50.1.2.3 (r749679 ASSRT)"'

for line in fileinput.input(filename, inplace=True, backup='.bak'):
    if text1_to_search.match(line):
        print("match")
    print(text1_to_search.sub(replacement1_text, line))

Upvotes: 3

Views: 42

Answers (1)

poke
poke

Reputation: 387687

With regular expressions, you can use capturing groups to capture individual parts of the search query and make those available in the result. When replacing strings with something else, you can then also use backreferences to refer to the value of those groups.

Capturing groups are created by simply wrapping things with parentheses. You have already used non-capturing groups in your expression, which are basically capturing groups prefixed by ?: which will cause them not to be available.

So in your case, you can simply wrap your r\d+ part with parentheses:

re.compile(r'#define\s+EPI_VERSION_STR\s+"\d+(?:\.\d+)+\s+\(TOB\)\s+\((r\d+) ASSRT\)"')
#                                                                     ^^^^^^

And then, in your replacement string, you can use \\1 to refer to that value:

replacement1_text = '#define EPI_VERSION_STR         "9.130.27.50.1.2.3 (\\1 ASSRT)"'

Simplified example:

>>> s = '#define ... "9.130.27.50.1.2.3 (r749679 ASSRT)"'
>>> re.sub('#define .+\((r\d+) ASSRT\)"', '... (\\1 ASSRT)', s)
'... (r749679 ASSRT)'

Upvotes: 2

Related Questions