2017-06-07 4 views
1

Ich weiß, es gibt ähnliche Fragen wie zuvor gefragt, aber ich möchte eine benutzerdefinierte Operation tun, und ich weiß nicht, wie es geht. Ich möchte eine Reihe von Daten mit einem regulären Ausdruck spalten wie, aber dieses Mal, wie ich weiß, dass das Anfangszeichen und das letzte Zeichen wie:Regulärer Ausdruck Wildcard Matching Split mit Java Split-Methode

String myString="Google is a great search engine<as:...s>"; 

The < als: und s> ist der Anfang und Schließen Zeichen die ... ist dynamisch, die ich ihren Wert vorhersagen kann nicht

ich mag die Zeichenfolge von Anfang an spalten können < als: bis zum Ende s> mit dem dynamischen String drin.

Like:

myString.split("<as:/*s>"); 

So ähnlich. Ich möchte auch alle Vorkommen der < als: .. s> in der Zeichenfolge erhalten. Ich weiß, dass dies mit Regex getan werden kann, aber ich habe es noch nie zuvor getan. Ich brauche einen einfachen und sauberen Weg, dies zu tun. Vielen Dank im Voraus

Antwort

0

Anstatt eine .split(), würde ich nur mit Pattern und Matcher extrahieren. Dieser Ansatz findet alles zwischen <as: und s> und extrahiert es in eine Erfassungsgruppe. Gruppe 1 hat dann den gewünschten Text.

public static void main(String[] args) 
{ 
    final String myString="Google is a great search engine<as:Some stuff heres>"; 

    Pattern pat = Pattern.compile("^[^<]+<as:(.*)s>$"); 

    Matcher m = pat.matcher(myString); 
    if (m.matches()) { 
     System.out.println(m.group(1)); 
    } 
} 

Ausgang:

Einige Sachen hier

Wenn Sie den Text am Anfang benötigen, können Sie es in einer Capture-Gruppe als auch setzen.

Edit: Wenn mehr als eine <as...s> in der Eingabe sind, wird das Folgende alle sammeln. Edit 2: erhöhte die Logik. Prüfungen für die Leere hinzugefügt.

public static List<String> multiEntry(final String myString) 
{ 
    String[] parts = myString.split("<as:"); 

    List<String> col = new ArrayList<>(); 
    if (! parts[0].trim().isEmpty()) { 
     col.add(parts[0]); 
    } 

    Pattern pat = Pattern.compile("^(.*?)s>(.*)?");   
    for (int i = 1; i < parts.length; ++i) { 
     Matcher m = pat.matcher(parts[i]); 
     if (m.matches()) { 
      for (int j = 1; j <= m.groupCount(); ++j) { 
       String s = m.group(j).trim(); 
       if (! s.isEmpty()) { 
        col.add(s); 
       } 
      } 
     } 
    } 

    return col; 
} 

Ausgang:

[Google ist eine große Suchmaschine Einige Sachen heress ist hier Facebook, Mehr Stuff, etwas anderes am Ende]

bearbeiten 3: Diese approach verwendet find und looping, um das Parsing durchzuführen. Es verwendet auch optionale Erfassungsgruppen.

public static void looping() 
{ 
    final String myString="Google is a great search engine" 
      + "<as:Some stuff heresss>Here is Facebook<as:More Stuffs>" 
      + "Something else at the end" + 
      "<as:Stuffs>" + 
      "<as:Yet More Stuffs>"; 

    Pattern pat = Pattern.compile("([^<]+)?(<as:(.*?)s>)?"); 

    Matcher m = pat.matcher(myString); 
    List<String> col = new ArrayList<>(); 

    while (m.find()) { 
     String prefix = m.group(1); 
     String contents = m.group(3); 

     if (prefix != null) { col.add(prefix); } 
     if (contents != null) { col.add(contents); } 
    } 

    System.out.println(col); 
} 

Ausgang:

[Google ist eine große Suchmaschine Einige Sachen heress ist hier Facebook, Mehr Stuff, etwas anderes am Ende, Stuff, immer noch mehr Stuff]

Zusätzliche Bearbeitung: schrieb einige schnelle Testfälle (mit super gehackter Hilfsklasse), um die Validierung zu unterstützen.Dieses Allpaß (aktualisiert) multiEntry:

public static void main(String[] args) 
{ 
    Input[] inputs = { 
      new Input("Google is a great search engine<as:Some stuff heres>", 2), 
      new Input("Google is a great search engine" 
        + "<as:Some stuff heresss>Here is Facebook<as:More Stuffs>" 
        + "Something else at the end" + 
        "<as:Stuffs>" + 
        "<as:Yet More Stuffs>" + 
        "ending", 8), 
      new Input("Google is a great search engine" 
          + "<as:Some stuff heresss>Here is Facebook<as:More Stuffs>" 
          + "Something else at the end" + 
          "<as:Stuffs>" + 
          "<as:Yet More Stuffs>", 7), 
      new Input("No as here", 1),  
      new Input("Here is angle < input", 1), 
      new Input("Angle < plus <as:Stuff in as:s><as:Other stuff in as:s>", 3), 
      new Input("Angle < plus <as:Stuff in as:s><as:Other stuff in as:s>blah", 4), 
      new Input("<as:To start with anglass>Some ending", 2), 
    }; 


    List<String> res; 
    for (Input inp : inputs) { 
     res = multiEntry(inp.inp); 
     if (res.size() != inp.cnt) { 
      System.err.println("FAIL: " + res.size() 
      + " did not match exp of " + inp.cnt 
      + " on " + inp.inp); 
      System.err.println(res); 
      continue; 
     } 
     System.out.println(res); 
    } 
} 
+0

Vielen Dank @kelvinO, aber ich brauche noch die Zeichenfolge geteilt durch , so kann ich eine Reihe von meinem String zu bekommen. Eigentlich baue ich eine ausgeklügelte Lucene-Suchanwendung, die dynamische Felder indizieren muss, und ich möchte hier ein paar Dinge als dynamisches Feld für die Indizierung verwenden. Ich muss ein Array aller Vorkommen von in der Zeichenfolge oder lassen Sie uns sagen, Dokument –

+0

@MichaelDawn, OK, fügte einen Looping-Ansatz hinzu. Sie können bei Bedarf auch die '' zurückstellen. – KevinO

+0

bekomme Fehler in dieser Zeile Liste col = new ArrayList <>() ;. Gibt es irgendeine Klasse, die ich importieren muss, um die Liste zu verwenden col = new ArrayList <>(); –