2013-11-22 21 views
5

ich lerne, wie regex zu gebrauchen:Regex Best Practices

Ich bin in einer Textdatei zu lesen, die in Abschnitte von zwei verschiedenen Arten aufgespalten wird, abgegrenzt durch <:==]:> und <:==}:>. Ich muß für jeden Abschnitt wissen, ob es ein ] oder }, so kann ich nicht einfach tun

pattern.compile("<:==]:>|<:==}:>"); pattern.split(text) 

dies zu tun:

pattern.compile("<:=="); pattern.split(text) 

Werke, und dann kann ich an den ersten char anschauen in jedem Teilstring, aber das scheint schlampig zu mir, und ich denke, ich bin nur darauf zurückgreifen, weil ich nicht völlig begreifen, was ich über Regex verstehen muss:

Was wäre die beste Praxis hier? Gibt es auch eine Möglichkeit, eine Zeichenfolge aufzuteilen, während das Trennzeichen in den resultierenden Zeichenfolgen verbleibt, so dass jedes mit dem Trennzeichen beginnt?

EDIT: die Datei abgelegt wird wie folgt aus:

Old McDonald had a farm 
<:==}:> 
EIEIO. And on that farm he had a cow 
<:==]:> 
And on that farm he.... 
+0

Meine erste Lösung (das Trennzeichen in einer Erfassungsgruppe einschließt) erscheint nicht in Java arbeiten (andere Sprachen wie Python würde gearbeitet haben), also muss ich dies zu überdenken. Können Sie eine kleine Beispieldatei bereitstellen? Ich bin mir nicht ganz sicher, ob ich verstehe, wie genau die Abschnitte abgegrenzt sind. Sind sie von Trennzeichenpaaren umgeben oder beginnt ein Abschnitt nach einem Trennzeichen und endet mit dem nächsten Trennzeichen? –

+0

@TimPietzcker Ja, ich hatte die gleiche Erkenntnis. Sehen Sie meine Bearbeitung für ein Beispiel, wie die Datei angelegt ist. Sie sind keine Paare von Delimetern, deren Ende jeweils durch den Beginn des nächsten signalisiert wird. Auch sollte ich beachten, dass <:?:> mehrere andere Arten von Tags bedeuten – drewmoore

+0

Also was genau willst du als Ausgang? Der Textabschnitt zusammen mit einem ']' oder '}'? Wenn ja, was willst du dann für den ersten/letzten Abschnitt, der nicht abgegrenzt ist? Brauchen Sie den Textabschnitt oder genügt es, nur die Trennzeichen zu haben? – OGHaza

Antwort

6

Es kann eine bessere Idee nicht split() für diesen Einsatz. Sie könnten stattdessen ein Spiel tun:

List<String> delimList = new ArrayList<String>(); 
List<String> sectionList = new ArrayList<String>(); 
Pattern regex = Pattern.compile(
    "(<:==[\\]}]:>)  # Match a delimiter, capture it in group 1.\n" + 
    "(     # Match and capture in group 2:\n" + 
    " (?:    # the following group which matches...\n" + 
    " (?!<:==[\\]}]:>) # (unless we're at the start of another delimiter)\n" + 
    " .    # any character\n" + 
    ")*    # any number of times.\n" + 
    ")     # End of group 2", 
    Pattern.COMMENTS | Pattern.DOTALL); 
Matcher regexMatcher = regex.matcher(subjectString); 
while (regexMatcher.find()) { 
    delimList.add(regexMatcher.group(1)); 
    sectionList.add(regexMatcher.group(2)); 
} 
+1

Sieht so aus, als hättest du das komplett geknackt. Ich denke, die Antwort auf alle Ihre Fragen ist Ja. Für Details, lesen Sie dieses [reguläre Ausdrücke Tutorial von Jan Goyvaerts] (http://www.regular-expressions.info/tutorial.html), besonders die Abschnitte über [einfangende Gruppen] (http: //www.regular-expressions .info/brackets.html) und [lookaround-Assertionen] (http://www.regular-expressions.info/lookaround.html). Was deine letzte Frage angeht, kannst du genauer sein? Vielleicht in Form einer anderen Frage, da Kommentare dafür nicht wirklich gut geeignet sind? –

+0

Ich mag dieses Beispiel mit den Kommentaren, aber beachten Sie, dass eine statische Regex in der Regel statisch (einmal) kompiliert und mehrmals wiederverwendet wird. Siehe auch: http://stackoverflow.com/questions/4935216/shouldnt-static-patterns-always-be-static siehe auch http://stackoverflow.com/questions/1360113/is-java-regex-thread-safe –