Abul Hasnat
Abul Hasnat

Reputation: 1631

how to reverse a regex in python?

My regex is something like below

    text = 'id 5 result pass
            id 4 result fail
            id 3 result fail
            id 2 result fail
            id 1 result pass'

    for i in re.finditer('id (.+?) result (.+)', text): 
         id = i.group(1)
         result = i.group(2)
         print 'id' 
         print 'result' 

The output is OK. But how do I reverse it to get the results in the other order where id will start from 1 with the pass or fail result

Upvotes: 5

Views: 3869

Answers (4)

Edward K. Ream
Edward K. Ream

Reputation: 189

When using finditer to change text we want to discover the changes first, and then make the changes in reverse order. Something like this:

# Pass 1: Find all replacements without changing the text.
replacements = []
for mo in pattern.finditer(text):
    # This may be arbitrarily complicated...
    << compute old, new text based on mo >>
    replacements.append((old, new),)

# Pass 2: Safely make all replacements by making them in reverse order.
for old, new in reversed(replacements):
    text = text.replace(old, new)

Upvotes: 1

HennyH
HennyH

Reputation: 7944

A good way is (which will be faster than using a lambda in the sorted):

sorted(re.finditer(...,text),key=attrgetter('group'),reverse=True):

Or you could turn the iterator into a list and reverse it:

for i in reversed(list(re.finditer('id (.+?) result (.+)', text))): 

Upvotes: 6

John La Rooy
John La Rooy

Reputation: 304137

You could sort by the value of the id. This will also work ok if the records are originally in a random order.

for i in sorted(re.finditer('id (.+?) result (.+)', text), key=lambda m:int(m.group(1))):

In the example given, the sort has O(n) complexity, since timsort detects the input as a single "run"

Upvotes: 1

llb
llb

Reputation: 1741

Assign the finditer call to a list and reverse it.

matches = list(re.finditer(...))
matches.reverse()

for i in matches:
   # etc.

Upvotes: 4

Related Questions