2013-07-05 1 views
5

Es gibt einige Saiten:Wie kann ich mit beiden regulären Ausdrücke passen, wenn die Regex Gruppe verschachtelt ist?

111/aaa 
111/aaa|222/bbb 

Sie sind in der Form des Ausdrucks:

(.*)/(.*)(|(.*)/(.*))? 

Ich habe versucht, es zu benutzen, um eine Zeichenfolge zu entsprechen und die Werte extrahieren:

var rrr = """(.*)/(.*)(|(.*)/(.*))?""".r 

"123/aaa|444/bbb" match { 
    case rrr(pid,pname, cid,cname) => println(s"$pid, $pname, $cid, $cname") 
    case _ => println("not matched ?!") 
} 

aber es druckt:

not matched ?! 

Und ich will bekommen:

123, aaa, 444, bbb 

Wie es zu beheben?


UPDATE

Vielen Dank für @BartKiers und @ Barmar der Anser, dass fand ich meine Regex einige Fehler hat, und fand schließlich diese Lösung:

var rrr = """(.*?)/(.*?)([|](.*?)/(.*?))?""".r 

"123/aaa|444/bbb" match { 
    case rrr(pid,pname, _, cid,cname) => println(s"$pid, $pname, $cid, $cname") 
    case _ => println("not matched ?!") 
} 

Es funktioniert, aber man kann sehen, gibt es eine _ die eigentlich nicht sinnvoll ist. Gibt es eine Möglichkeit, die regex neu zu definieren, die ich rrr(pid,pname,cid,cname) nur schreiben kann, es passen?

+0

'|' ist ein Sonderzeichen in Regexp, Sie müssen es entkommen. – Barmar

+0

Ich denke, ich kann Nicht-Capture-Gruppe verwenden: '?:' – Freewind

+0

Ja, wenn es Gruppen gibt, die Sie nur für das Muster verwenden, nicht zu erfassen, das ist, was Nicht-Capture-Gruppen sind. – Barmar

Antwort

5

.* zu viel Rückzieher becuase .* würde die komplette Zeichenfolge übereinstimmen und dann eins nach dem anderen gehen zuerst führen könnten zurück, bis er entspricht dem ersten /.

Auch wird es nicht die Werte in Gruppen erfassen richtig, wie Sie es ..

erwarten Sie .*?

Ihre regex sollte

^(.*?)/(.*?)(?:\|(.*?)/(.*?))?$ 

sein verwenden sollten, gäbe es nicht ein Leistungsunterschied für kleine Strings sein, aber es würde die Werte in der richtigen Gruppe erfassen

Beachten Sie die ?: in der Regex, bedeutet es die Gruppe (?:\|(.*?)/(.*?))? nicht erfassen kann. Es werden also nur 4 Untergruppen als Ergebnis sein.

+0

Danke für das Zeigen meines anderen großen Fehlers – Freewind

+0

Das ist brilliant +1 –

3

versuchen zu fliehen die |, die das logische ODER in regex ist:

var rrr = """(.*)/(.*)(\|(.*)/(.*))?""".r 
Verwandte Themen