2009-03-01 20 views

Antwort

212

Sie sollten in der Lage sein, nicht gierige Quantoren zu verwenden, und zwar * ?. Du wirst wahrscheinlich folgendes wollen:

Pattern MY_PATTERN = Pattern.compile("\\[(.*?)\\]"); 

Dies wird Ihnen ein Muster, das die Zeichenfolge übereinstimmen und den Text innerhalb der eckigen Klammern in der ersten Gruppe gesetzt. Werfen Sie einen Blick auf die Pattern API Documentation für weitere Informationen.

die Zeichenfolge zu extrahieren, Sie so etwas wie die folgende verwenden:

Matcher m = MY_PATTERN.matcher("FOO[BAR]"); 
while (m.find()) { 
    String s = m.group(1); 
    // s now contains "BAR" 
} 
+13

Es ist erwähnenswert, dass, wenn es eine neue Zeile zwischen den eckigen Klammern gibt, wird dies fehlschlagen und Sie sollten das Pattern.DOTALL Flag verwenden, um dies zu vermeiden. – cletus

+0

Wie würden Sie dann das obige Muster verwenden, um die Zeichenfolge mit der Zeichenfolge BAR zu extrahieren? Ich schaue mir die Pattern-API und die Matcher-API an, bin mir aber immer noch nicht sicher, wie ich die Zeichenfolge selbst erhalten soll. – digiarnie

+0

@cletus: Guter Anruf! @digiarnie: Ich habe eine Antwort zu der Antwort hinzugefügt, die einen Strohmann-Code enthält, um das Spiel zu bekommen. –

29

die ohne reguläre Ausdrücke Weise:

String input = "FOO[BAR]", extracted; 
extracted = input.substring(input.indexOf("["),input.indexOf("]")); 

alternativ für eine etwas bessere Leistung/Speicherauslastung (dank Hosam) :

String input = "FOO[BAR]", extracted; 
extracted = input.substring(input.indexOf('['),input.lastIndexOf(']')); 
+1

Ich würde 'lastIndexOf (')')' stattdessen verwenden, die geschachtelte Klammern behandeln würde. Außerdem glaube ich, dass die Benutzung von 'indexOf (char)' schneller ist als 'indexOf (String)'. –

+0

einverstanden, ich füge eine Bearbeitung hinzu – zaczap

+0

Gern geschehen. Ihre Anmerkung zur Leistung ist ebenfalls sehr relevant, da 'lastIndexOf' sicherlich schneller ist, um die schließende Klammer zu finden. –

2

ich denke, Ihr regulärer Ausdruck aussehen würde:

/FOO\[(.+)\]/ 

Angenommen, FOO wird konstant sein.

So setzen diese in Java:

Pattern p = Pattern.compile("FOO\\[(.+)\\]"); 
Matcher m = p.matcher(inputLine); 
+0

FOO [BAR] FOO [BAZ] -> mit Ihrer Regex wird zurück: "BAR] FOO [BAZ" –

0

unter der Annahme, dass keine andere eckigen Klammern innerhalb,/FOO \ [([^ \]] *) \]/

0

Ich darf definiere, dass ich eine maximale Anzahl von Nicht-Zeichen zwischen [ und ] haben möchte. Diese müssen mit Backslashes maskiert werden (und in Java müssen diese erneut maskiert werden), und die Definition von non ist eine Zeichenklasse, also innerhalb von [ und ] (d. H. [^\\]]). Das Ergebnis:

FOO\\[([^\\]]+)\\] 
5

Wenn Sie einfach brauchen, um alles, was zwischen [] ist, kann die Sie \[([^\]]*)\] wie folgt verwenden:

Pattern regex = Pattern.compile("\\[([^\\]]*)\\]"); 
Matcher m = regex.matcher(str); 
if (m.find()) { 
    result = m.group(); 
} 

Wenn Sie es brauchen die Form zu sein, Sie identifier + [ + content + ] dann kann das Extrahieren des Inhalts nur einschränken, wenn der Bezeichner ein alphanumerischer Wert ist:

Dies wird gültig Dinge wie Foo [Bar] oder myDevice_123["input"] zum Beispiel.

Haupt Ausgabe

Das Hauptproblem ist, wenn Sie den Inhalt, so etwas entpacken:

FOO[BAR[CAT[123]]+DOG[FOO]] 

Die Regex wird nicht funktionieren und wird BAR[CAT[123 und FOO zurück.
Wenn wir die Regex zu \[(.*)\] ändern dann sind wir in Ordnung, aber dann, wenn Sie versuchen, den Inhalt von komplexeren Dingen zu extrahieren wie:

FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]] 

Keine des Regexes funktionieren wird.

Die genaueste Regex, um den richtigen Inhalt in allen Fällen zu extrahieren, wäre sehr viel komplexer, da es [] Paare ausgleichen müsste und Ihnen Inhalt geben würde.

Eine einfachere Lösung

Wenn Ihre Probleme sind komplex und der Inhalt des willkürlichen [] bekommen, könnte man stattdessen die Paare von [] balancieren und die Zeichenfolge mit einfachen altem Code Rathe als ein Regex extrahieren:

Dies ist mehr Pseudo-Code als realer Code, ich bin kein Java-Coder, also weiß ich nicht, ob die Syntax korrekt ist, aber es sollte leicht genug sein, um zu verbessern.
Was zählt ist, dass dieser Code funktionieren sollte und Sie den Inhalt des [] extrahieren können, wie komplex es auch ist.

1
String input = "FOO[BAR]"; 
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]")); 

Dadurch wird der Wert zwischen dem ersten '[' und zuletzt ']'

Foo [Bar] => Bar

Foo [Bar [Test]] => Bar [Test] zurückkehren

Hinweis: Sie sollten eine Fehlerprüfung hinzufügen, wenn die Eingabezeichenfolge nicht korrekt formatiert ist.

17

Dies ist ein funktionierendes Beispiel:

RegexpExample.java

package org.regexp.replace; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class RegexpExample 
{ 
    public static void main(String[] args) 
    { 
     String string = "var1[value1], var2[value2], var3[value3]"; 
     Pattern pattern = Pattern.compile("(\\[)(.*?)(\\])"); 
     Matcher matcher = pattern.matcher(string); 

     List<String> listMatches = new ArrayList<String>(); 

     while(matcher.find()) 
     { 
      listMatches.add(matcher.group(2)); 
     } 

     for(String s : listMatches) 
     { 
      System.out.println(s); 
     } 
    } 
} 

Es zeigt:

value1 
value2 
value3 
0

Gefällt Ihnen dieses seine Arbeit, wenn Sie einige Zeichenfolge analysieren wollen, die von mYearInDB kommt .toString() = [2013] Es wird für mich 2013

Matcher n = MY_PATTERN.matcher("FOO[BAR]"+mYearInDB.toString()); 
while (n.find()) { 
extracredYear = n.group(1); 
// s now contains "BAR" 
    } 
    System.out.println("Extrated output is : "+extracredYear); 
5
import java.util.*; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public static String get_match(String s, String p) { 
    // returns first match of p in s for first group in regular expression 
    Matcher m = Pattern.compile(p).matcher(s); 
    return m.find() ? m.group(1) : ""; 
} 

get_match("FOO[BAR]", "\\[(.*?)\\]") // returns "BAR" 

public static List<String> get_matches(String s, String p) { 
    // returns all matches of p in s for first group in regular expression 
    List<String> matches = new ArrayList<String>(); 
    Matcher m = Pattern.compile(p).matcher(s); 
    while(m.find()) { 
     matches.add(m.group(1)); 
    } 
    return matches; 
} 

get_matches("FOO[BAR] FOO[CAT]", "\\[(.*?)\\]")) // returns [BAR, CAT] 
0

Diese regexp Werke geben:

form\[([^']*?)\] 

Beispiel:

form[company_details][0][name] 
form[company_details][0][common_names][1][title] 

Ausgang:

Match 1 
1. company_details 
Match 2 
1. company_details 

Getestet am http://rubular.com/