Search code examples
pythonregexpython-3.xserial-portregular-language

Python - serial read and use of regular expressions to group data


I am reading data from the serial line using basic python code. I store that data to a local variable and then use re.search to look for specific values. I then group the data using match.group which for the most part works well.

My issue is that sometimes I get data from another place in the serial data which is incorrect based on the pattern that I'm looking for. Is there any way I can make this more reliable?

Some snippets from the python function:

ser = serial.Serial('COM' + port, 115200, timeout=0, parity=serial.PARITY_NONE, 
stopbits=serial.STOPBITS_ONE, rtscts=0)

data = ser.read(9999)

ser.close()

match =  re.search(r'Result1:({0}).*(\\r\\n)Result2:(\d)(\d)(\\r\\n)Result3:(\d*)'.format(Result1), 
str(data))

Result1= match.group(1)
Result2= match.group(3) + match.group(4)
Result3= (match.group(6))

What the serial data looks like when the code executes and returns the expected result:

Result1:11111111(0x11111111)\r\nResult2:09\r\nResult3:1000\r\nResult4:1\r\nResult5:20 Result6:1\r\nResult7:02\r\n[Thats a RF Datagram:141490\r\n\Result1:11111111(0x11111111) \r\nResult2:09\r\nResult3:1000

What the serial data looks like when the code executes and returns the unexpected result:

Result1:11111111(0x11111111)\r\nResult2:09\r\nResult3:1000\r\nResult4:1\r\nResult5:20 Result6:1\r\nResult7:02\r\n[Thats a RF Datagram:141490\r\n\Result1:22222222(0x11111111) \r\nResult2:07\r\nResult3:1250

It looks like the values for Result2 and/or Result3 is picked up correctly most of the time but when there are different values on the final line as shown above (example: 07 and 1250), it fails against expected results. I assumed that the re.search expression shown above is looking for the results 1-3 in order but it's just not reliable.

Could anyone shed a little light on where I might be going wrong with this one?

Thanks.


Solution

  • You are using .* in your pattern, which is greedy, so it will match as much as possible skipping over Result6 and 7 until it finds the second Result2:.

    Use .*? instead, which is the non-greedy version which matches as little as possible. See re.