2016-07-12 8 views
2

So habe ich diese großen mathematischen Ausdrücke in einer Zeichenfolge gespeichert, die ich aus SymPy habe, und ich versuche es zu formatieren, so dass ich es in Mathematica verwenden kann.Regex zu ersetzen() mit [] um Funktionsargumente

Ich möchte alles, was wie 'sin(arg)' zu Sin[arg] aussieht, ändern, aber ich muss es auch für Cosinus arbeiten lassen. arg kann irgendeine von diesen sein: theta1, theta2, theta3, theta4, theta5.

Es gibt eine Tonne von anderen Klammern in der Zeichenfolge, die ich nicht ersetzen möchte, so dass es nur sin und cos Klammern bewirken muss.

Für S = "cos(theta1)" Ich habe versucht:

S = S.replace("cos", "Cos") 
S = S.replace("sin", "Sin") 
S = re.sub(r"Sin|Cos(\()theta1|theta2|theta3|theta4|theta5", "[", S) 
S = re.sub(r"Sin|Cos\(theta1|theta2|theta3|theta4|theta5(\))", "]", S) 

Und S wird:

'[)' 

Ich dachte, mit den Klammern um die \( und \) bedeuten würde es nur die spezifischen Gruppen ersetzt, aber anscheinend nicht. Gibt es eine andere Funktion als re.sub, die ich verwenden sollte?

P.S. Gibt es eine Möglichkeit, die sin -> Sin Ersatz in die Regex zu quetschen?

Antwort

3
def replacer(m): 
    return m.group(1).capitalize()+"["+m.group(2)+"]" 

re.sub("([a-z]+)\(([a-zA-Z0-9 ]*)\)",replacer,"cos(Theta1)") 

Ich denke, ... vielleicht ...

+0

ehrfürchtig. Vielen Dank! –

1

Da Ihr nur Argumente theta1 durch theta5 sein kann, können Sie einfach tun den Ersatz

sin\((theta[1-5])\) 

mit

Sin[\1] 

und

cos\((theta[1-5])\) 

mit

Cos[\1] 

Die \1 ist ein Rückreferenzierung, es Wert aus der ersten angepassten geklammerten Gruppe in der ursprünglichen Zeichenfolge, in diesem Fall Ihr Argument nehmen.

Aber ich würde mit Joran's Antwort gehen.

+0

Ich denke, diese Antwort ist einfach so gut wie meine, P –

+0

Ah, mehrere Ansätze tauchen auf. Was würde Guido tun? –

+0

Ich werde mit diesen Rückreferenzen spielen müssen. Vielen Dank! –

1
import re 

if __name__ == '__main__': 
    test = 'sin (theta1)' 
    regex = (
     r'(sin|cos)'  # group # 1: sin or cos 
     r'\s*'   # zero or more spaces 
     r'\('   # opening bracket 
     r'\s*'   # zero or more spaces 
     r'(theta[1-5])' # group #2 with your parameter 
     r'\s*'   # zero or more spaces 
     r'\)'   # closing bracket 
     r'\s*'   # zero or more spaces 
    ) 

    result = re.sub(regex, r'\1[\2]', test,).capitalize() 
    print(result) 
+1

Aber das macht die 'theta's in' Theta ' –

+0

Sie haben Recht, muss das beheben ... Fixed mit' Großschreibung' Methode anstelle von 'title'. Vielen Dank. – grundic

+0

Ja, 's/title/capitalize' war das Ticket. :) –

0

Sie Teile des Musters angeben, die verbraucht wird, nicht (ersetzt) ​​mit Blick behinds (?<=...) und Lookaheads (?=...):

S = "cos(theta1)" 

S = S.replace("cos","Cos").replace("sin","Sin") 

S = re.sub(r"(?<=Sin|Cos)\((?=theta1|theta2|theta3|theta4|theta5)", "[", S) 
S = re.sub(r"(?<=(Sin|Cos)\[(theta1|theta2|theta3|theta4|theta5))\)", "]", S) 

assert S == 'Cos[theta1]' 
+0

Ok, so '? <=' Und '?= 'innerhalb einer Capture-Gruppe sagt' re', die Gruppe zu ignorieren, aber wird das nur verwendet, wenn Sie alles wegwerfen, was nicht in einer Lookahead/hinter-Gruppe ist? –

+0

Das Muster ist im Grunde "diese einzelne Klammer nur wenn vorangestellt von ... und gefolgt von ..." So ist es nur technisch das eine Zeichen, ich bin nicht wirklich sicher, wie man es anders als das aber ich bin ziemlich sicher, dass andere Verwendungen existieren. –