2016-09-04 4 views
0

Ich habe einen folgenden Ausschnitt, in der Regel möchte ich arithmetischen Ausdruck (mit negativen Zahlen) zu Token teilen.Arithmetische Ausdrücke in Python mit Regexps teilen

import re 
import collections 

NUM  = r'(?P<NUM>-?\d+)' 
PLUS = r'(?P<PLUS>\+)' 
MINUS = r'(?P<MINUS>-)' 
TIMES = r'(?P<TIMES>\*)' 
DIVIDE = r'(?P<DIVIDE>/)' 
LPAREN = r'(?P<LPAREN>\()' 
RPAREN = r'(?P<RPAREN>\))' 
WS  = r'(?P<WS>\s+)' 

Token = collections.namedtuple('Token', ['type', 'value']) 

def generate_tokens(text): 

    pattern = re.compile('|'.join((NUM, PLUS, MINUS, TIMES, DIVIDE, LPAREN, RPAREN, WS))) 

    scanner = pattern.scanner(text) 
    for m in iter(scanner.match, None): 
     token = Token(m.lastgroup, m.group()) 

     if token.type != 'WS': 
      yield token 

expr = "2-2" 
out = [token for token in generate_tokens(expr)] 
for token in out: 
    print(token) 

Und es gibt Problem mit Splitting negativen Zahlen mit diesem Code ausgegeben wird

Token(type='NUM', value='2') 
Token(type='NUM', value='-2') 

Aber soll

Token(type='NUM', value='2') 
Token(type='MINUS', value='-') 
Token(type='NUM', value='2') 

Wie dieses Problem beheben?

+0

Versuchen Sie, Ihre NUM-Gruppe nach der Gruppe MINUS zu setzen, so dass das Muster mit dem Minuszeichen zuerst übereinstimmt –

+0

@PhuNgo Aber dann negative Zahlen nicht zusammenpassen. – paruwa

+0

Fügen Sie eine Überprüfung hinzu (z. B. '(?! ^)'), Um sicherzustellen, dass ein Ausdruck nicht mit Operatoren beginnt –

Antwort

0

Ich denke, der einfachste Weg besteht darin, Ausdrücke zu erstellen, indem man jeden Teil mit Leerzeichen trennt.

ex.

expr= '2 - -2' 
Token(type='NUM', value='2') 
Token(type='MINUS', value='-') 
Token(type='NUM', value='-2') 

Das Problem ist, dass der Computer dosen't wissen wheter Sie vergessen haben ein Minuszeichen „2-2“ Ausdruck hinzuzufügen, oder wenn man wollte 2 bis subtrahieren - 2, die 0. Ich würde Ich denke, es sollte kein Problem sein, um genau zu spezifizieren, wie der Input gegeben werden sollte.