2012-04-01 17 views
0

Ich habe eine Zeichenfolge, die wie etwas aussieht:Regex immer falsche Ausgabe in Java

" 'a' b '(dfg (1 2))' (3 4) (ad) d"

Und was ich versuche Spiel zu tun, damit ich diese Ausgabe erhalten:

'a,' b '(dfg (1 2)),' (3, 4), (ad), d

Ich bin derzeit:

"'\(.*\)|\(\.*\)|'\w+|\w+" 

Aber es gibt ein Problem, das ich in der Verwendung dieses runned habe, zum Beispiel, wenn ich schreibe

‚(abc) (df)

es kehrt

‚(abc) (df)

statt

‚(abc), (df)

So ist meine Frage, ob es eine Möglichkeit, dies mit regex zu lösen ist, oder muss ich diese eine andere lösen Weg?

+0

Da es nicht von Regex allein geparst werden kann, haben Sie eine bevorzugte Sprache für eine alternative Lösung? – cmbuckley

+0

Welcher Regex-Geschmack? – Qtax

+0

@cbuckley, Ich schreibe gerade das Programm in Java. – warbio

Antwort

4

Die Antwort ist nein.

Die Sprache, die Sie analysieren möchten, ist nicht regular, es ist context-free. Sie können es also nicht mit Regex analysieren.

Wenn Sie interessiert sind, hier ist die Grammatik:

S->SS|e; 
S->'(A); 
A-> AA|(A)|w+; 

Es ist keine regelmäßige, da Sie FSM nicht bauen kann, sie zu vertreten, was wahr ist, falls Sie rekursiv Klammer Strukturen umfassen.

Nun, was auch immer. Lass uns die Frage "Wie?" Beantworten. Überquere den String vom ersten Zeichen. Sobald Sie einen Bindestrich gefunden haben, fangen Sie an, Klammern zu zählen. Das Öffnen zählt für +1, das Schließen für -1. Sobald Sie eine schließende Klammer mit einem Zähler von null getroffen haben, fügen Sie nach dieser Klammer ein Komma ein. Problem gelöst:

'a 'b '(d f g (1 2)) '(3 4) (a d) d 
     |  | || 
     |  | |+-- counter = 0 on closing bracket, insert comma 
     |  | +--- counter = 1 
     |  +------- counter = 2 
     +-------------- start counting, counter = 1 

usw.

+0

Okay, ich denke, ich muss es anders machen, danke für die schnelle Antwort. – warbio

+1

Most ** regex Aromen sind nicht regelmäßig **. Passende kontextfreie Sprachen sind für PCRE kein Problem. Beispiel http://stackoverflow.com/questions/7434272/match-an-bn-cn-eg-aaabbbcccc-using-regular-expressions-pcre – Qtax

+0

@Qtax in der Tat ist es eher eine schlechte Übung, etwas ein "Regex" zu nennen Das ist nicht wirklich eine "Regex" :(Obwohl ich stimme zu, dass meine Antwort in der realen Welt nicht präzise sein kann, ist es im akademischen Kontext absolut richtig. – iehrlich

0

Wenn Sie PCRE oder dergleichen verwenden, Sie könnten ein Ausdruck wie:

'?(?:\w+|(\(?:([^()]+|(?1))*\))) 
0

Wenn ich richtig verstehe, wollen Sie ein Komma hinzufügen, bevor jedes Leerzeichen, außer in Klammern. Ist das richtig?

Wenn ja, könnte es einen Weg geben, es in Regex mit Lookaheads und Lookbehinds zu tun, aber es wird chaotisch schnell werden.Es ist besser, alle Begriffe zuerst zu trennen und dann Kommas hinzuzufügen, genau nach dem, was Sie wollen.