Best Method to Find Multiple String Occurrences in Python
Question: I need to be pointed in the right direction for this problem I'm working on:

Let's say I'm reading output from a C program as follows:

    
    
    while True:
        ln = p.stdout.readline()
        if '' == ln:
            break
        #do stuff here with ln
    

And my output looks like this line for line:

    
    
    TrnIq: Thread on CPU 37
    TrnIq: Thread on CPU 37 but will be moved to CPU 44
    IP-Thread on CPU 33
    FANOUT Thread on CPU 37
    Filter-Thread on CPU 38 but will be moved to CPU 51
    TRN TMR Test 2 Supervisor Thread on CPU 34
    HomographyWarp Traking Thread[0] on CPU 26
    

I want to capture "TrnIq: Thread on" and "37" as 2 separate variables: a
string and a number from output "TrnIq: Thread on CPU 37".

Its pretty well the same for the other lines to, for example capture
"HomographyWarp Traking Thread[0] on" and the # "26" from "HomographyWarp
Traking Thread[0] on CPU 26".

The only real challenge is for lines like this: "Filter-Thread on CPU 38 but
will be moved to CPU 51" on this line I need "Filer-Thread" and the # "51" not
the first # "38".

Python has so many different ways to do this I dont even know where to start!

Thanks in advance!


Answer: The following should return a tuple of the information assuming `ln` is a
single line of your data (edited to include converting the CPU value to an
int):

    
    
    match = re.match(r'(.*?)(?: on CPU.*)?(?: (?:on|to) CPU )(.*)', ln).groups()
    if match:
        proc, cpu = match.groups()
        cpu = int(cpu)
    

Example:

    
    
    >>> import re
    >>> for ln in lines:
    ...     print re.match(r'(.*?)(?: on CPU.*)?(?: (?:on|to) CPU )(.*)', ln).groups()
    ... 
    ('TrnIq: Thread', '37')
    ('TrnIq: Thread', '44')
    ('IP-Thread', '33')
    ('FANOUT Thread', '37')
    ('Filter-Thread', '51')
    ('TRN TMR Test 2 Supervisor Thread', '34')
    ('HomographyWarp Traking Thread[0]', '26')
    

Explanation:

    
    
    (.*?)          # capture zero or more characters at the start of the string,
                   #   as few characters as possible
    (?: on CPU.*)? # optionally match ' on CPU' followed by any number of characters,
                   #   do not capture this
    (?: (?:on|to) CPU )  # match ' on CPU ' or ' to CPU ', but don't capture
    (.*)           # capture the rest of the line
    

Rubular: <http://www.rubular.com/r/HqS9nGdmbM>

