I decided on a regular task from here :

You need to check Vasi Pupkin's homework, in which he wrote equality. For example, a record of the form “2 + 3 = 5” is correct, and “23 * 7 = 421” is incorrect, but correct. The correct entry of the expression will be called the sequence: number, operation ("+", "-", "*", "/"), number, equal sign, number. The number will be considered a sequence of one or more decimal digits, in front of which there can be one minus sign. There are no spaces in the correct expression record. In the output OUTPUT.TXT file, output “YES” if the specified entry is correct (ie, equality is an identity), “NO” if correct, but incorrect, and ERROR if the entry is incorrect.

Well, even the first test does not pass. For verification, I redid the solution into a function with asserts. Look who - where I blunted? All imaginable options passes ...

import re # ============================================================================= # # with open('INPUT.TXT') as f: # line = f.read() # ============================================================================= def t(line): mo = re.fullmatch(r'(?P<n1>-?\d+)(?P<oper>[-/\*\+])(?P<n2>-?\d+)=(?P<n3>-?\d+)', line) result = "ERROR" if len(line) <=100 and mo: n1 = int(mo.groupdict()['n1']) n2 = int(mo.groupdict()['n2']) n3 = int(mo.groupdict()['n3']) if max(n1,n2,n3)<30000 and min(n1,n2,n3)>-30000: oper = mo.groupdict()['oper'] if oper == "/" and n2==0: result = "NO" else: m = lambda x,y: x*y d = lambda x,y: x/y s = lambda x,y: x+y _ = lambda x,y: xy do = {"*":m, "/":d, "+":s, "-":_} result = "YES" if n3 == do[oper](n1,n2) else "NO" return result # ============================================================================= # with open('OUTPUT.TXT', 'w') as f: # f.write(result) # # ============================================================================= assert t("er") == "ERROR" assert t('1+-1=1') == "NO" assert t('1+-1=-0') == "YES" assert t('-31+-1=-32') == "YES" assert t('2*=3') == "ERROR" assert t('173') == "ERROR" assert t('2+2=a') == "ERROR" assert t('two plus three is five') == "ERROR" assert t('2+3=5') == "YES" assert t('3*7=20') == "NO" assert t('3*7=21') == "YES" assert t('3-7=-4') == "YES" assert t('0/7=0') == "YES" assert t('7/0=0') == "NO" assert t('---=-') == "ERROR" assert t('') == "ERROR" 
  • one
    Perhaps, in INPUT.TXT, at the end there is accidentally a newline character that you don’t delete (but this isn’t accurate) - andreymal
  • @andreymal 100%. Inserted line = line.replace('\n',"") and it all worked. Well, that ... 3 hours of torment because of the untidiness of administrators .... - Vasyl Kolomiets
  • one
    Use re.match(r'(?P<n1>-?\d+)(?P<oper>[-/*+])(?P<n2>-?\d+)=(?P<n3>-?\d+)$', line) - Wiktor StribiĹĽew
  • one
    @VasylKolomiets well, not that untidiness, line breaks at the end of files are standard practice in Unix-like operating systems. But the fact that in such tasks I have never met clarifications about the use of hyphenation, sad - andreymal

1 answer 1

re.fullmatch returns a matching object if the string, as an integer, fully matches the pattern , otherwise returns None ( see here ).

In your case, since there is a line break at the end of the line, you must either consider the whitespace characters in your regular expression by adding \s* at the end:

 re.fullmatch(r'(?P<n1>-?\d+)(?P<oper>[-/*+])(?P<n2>-?\d+)=(?P<n3>-?\d+)\s*', line) ^^^ 

or use re.match , and in a regular expression add $ , which finds the end of a line or a position before the last character in the line, if it is a newline character:

 re.match(r'(?P<n1>-?\d+)(?P<oper>[-/*+])(?P<n2>-?\d+)=(?P<n3>-?\d+)$', line) ^^^^^^ ^ 

Demo:

 import re line="-12+34=22\n" print(re.fullmatch(r'(?P<n1>-?\d+)(?P<oper>[-/*+])(?P<n2>-?\d+)=(?P<n3>-?\d+)\s*', line)) # => <_sre.SRE_Match object; span=(0, 10), match='-12+34=22\n'> print(re.match(r'(?P<n1>-?\d+)(?P<oper>[-/*+])(?P<n2>-?\d+)=(?P<n3>-?\d+)$', line)) # => <_sre.SRE_Match object; span=(0, 9), match='-12+34=22'>