简体   繁体   中英

pexpect.expect('(?<=Code:\s).*(?=[\r\n])') sometimes got unexpected result from multiline output

I'm new to learning python and pexpect and I'm trying to check if a dictionary is equal to a certain string from some command output but for some reason the string comparison fails on the rare occassion but passes most of the time.

So say I send some command called list to my terminal, it outputs details of a certain product:

->list
Color: Maroon Red
Height: 150cm
Code: 4KG-LV
Material: Aluminum
Brand: Toyota 
#and hundreds of more lines...

I have a variable that represents a dictionary that outputs this when I print it using print(license_type) :

{'license': '4kg-lv'}

I basically want to check if the code 4KG-LV from the output of the list command is equal to the value 4kg-lv from the license in the dictionary.

Doing this:

exp.sendline("list")
exp.expect('(?<=Code:\s).*(?=[\r\n])')
firstString = exp.after
print(firstString) 

parses the output of the list command using regex and gets/prints the value 4KG-LV .

If I were to put all of this in a python script and check if the two values are equal, it should pass the check as I printed those 2 strings out and they look identical on my terminal. However, when I try to check if the first string (the code from the list command) is equal to the dictionary value, it will pass as EQUAL 95% of the time, but on the rare occasion it fails the comparison for some reason and I have no idea why.

license_type = {'license': '4kg-lv'}
exp.sendline("list")
exp.expect('(?<=Code:\s).*(?=[\r\n])')
codeString = exp.after

firstString = codeString.lower().strip(' \t\n\r')
secondString = licenseType.get("type").lower().strip(' \t\n\r')

if firstString == secondString
    print("EQUAL")
else:
    print("NOT EQUAL")

I have lots of commands and output above this section of code and I'm not sure if maybe it's reading an extra space or \\n sometimes when I run the script? It fails the comparison maybe like once every 30-40 runs. Without the .strip(' \\t\\n\\r') it automatically fails every time, but adding that seems to make it pass most of the time but I'm not sure what's causing it to fail on the rare occasion.

Is it possible it's ignoring the spaces/tabs too late? Should I be adding strip.(' \\t\\n\\r') before .lower() ?

Seems like you should change

exp.expect('(?<=Code:\s).*(?=[\r\n])')

to

exp.expect('(?<=Code:\s)[^\r\n]*(?=[\r\n])')

otherwise, the greedy .* may possibly match cross newlines (depending on how fast the app outputs and how fast pexpect reads the data) , for example, "4KG-LV\\r\\nMaterial: Aluminum" .


Example:

A simple pexpect script foo.py :

import pexpect, sys

p = pexpect.spawnu('bash -c "echo : foo; ((RANDOM % 2)) && sleep .1; echo : bar" ')
p.expect('(?<=:\s).*(?=[\r\n])')
matched = p.after
p.expect(pexpect.EOF)

print('MATCHED: %s' % repr(matched) )

Try it:

$ for i in {1..10}; do python3 foo.py; done
MATCHED: 'foo\r\n: bar\r'
MATCHED: 'foo\r'
MATCHED: 'foo\r\n: bar\r'
MATCHED: 'foo\r'
MATCHED: 'foo\r'
MATCHED: 'foo\r'
MATCHED: 'foo\r'
MATCHED: 'foo\r\n: bar\r'
MATCHED: 'foo\r\n: bar\r'
MATCHED: 'foo\r\n: bar\r'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM