2010-09-23 12 views

Antwort

26
str.split("(?=[:;])") 

Dies gibt Ihnen das gewünschte Array, nur mit einem leeren ersten Element. Und:

str.split("(?=\\b[:;])") 

Dies wird das Array ohne das leere erste Element geben.

  • Der Schlüssel ist hier die (?=X) die eine Null-Breite positive Vorgriffs-(non-Capturing-Konstrukt) ist (siehe regex pattern docs).
  • [:;] Mittel „entweder oder“
  • \b ist Wortgrenze - es ist da, um die ersten : als Begrenzungszeichen nicht zu betrachten (da es der Beginn der Sequenz ist)
+0

'(? = X)' ist "positiver Lookahead der Nullweite", die nicht einfangende Gruppe ist '(?: X)'. Das würde mit der nicht-einfangenden Gruppe nicht richtig funktionieren ... –

+0

@Carlos Heuberger könnten Sie mehr erklären? Es funktioniert tatsächlich so (getestet), aber ich könnte etwas verpasst haben – Bozho

+1

es funktioniert, aber die Sequenz '(? = X)' heißt nicht "nicht einfangende Gruppe" oder zumindest nicht die einfache "nicht einfangende Gruppe" . Es heißt "positive Lookahead mit einer Breite von Null". Die "nicht einfangende Gruppe" ist "(?: X)". (Entschuldigung für mein schlechtes Englisch) –

4

Um die Separatoren halten Sie ein StringTokenizer verwenden:

new StringTokenizer(":alpha;beta:gamma;delta", ":;", true) 

, dass die Separatoren als Zeichen ergeben würde.

Um sie als Teil Ihrer Token zu verwenden, können Sie String#split mit lookahead verwenden.

+3

„StringTokenizer ein Legacy-Klasse ist“ – Bozho

+3

@Bozho Das stimmt, aber ich denke, diese besondere Anwendungsfall die Trennzeichen halten nicht sehr schön von String bedeckt ist #split, was ein detailliertes Regex-Wissen erfordert, um das zu erreichen. –

+0

wahr, es ist ein bisschen klarer mit StringTokenizer, da es die gewünschte Option als booleschen Parameter hat. +1, der Punkt über das Erbe ist immer noch gültig. – Bozho

-1

Unter der Annahme, dass Sie haben nur eine endliche Menge von Trennzeichen vor den Wörtern in Ihrer Zeichenkette (zB;,: usw.) Sie können die folgende Technik verwenden. (Entschuldigung für etwaige Syntaxfehler, aber es ist schon eine Weile her, seit ich Java verwendet)

String toSplit = ":alpha;beta:gamma;delta " 
toSplit = toSplit.replace(":", "~:") 
toSplit = toSplit.replace(";", "~;") 
//repeat for all you possible seperators 
String[] splitStrings = toSplit.split("~") 
+0

das ist einfacher. – Joset

+0

1. Es ist falsch, da es ein leeres 0. Element zurückgibt. 2. Es erhöht die Fehlerwahrscheinlichkeit aufgrund von Duplikaten (dh ":" muss mit "~:" gepaart werden). 3. Was passiert, wenn das spezielle Begrenzungszeichen "~" in einem der Teilstrings verwendet wird? –

+0

@Tony, Ich wählte "~" als Beispiel, aber jedes andere eindeutige Trennzeichen könnte verwendet werden, das zu dem verfügbaren Datensatz passt. Ich sehe nicht, wie es die Fehlerwahrscheinlichkeit erhöht - vielleicht könnten Sie diesen Punkt klären. Ich gebe zu, dass es ein leeres 0. Element zurücklässt, was ein Fehler dieses Ansatzes ist, aber ich wollte eine andere Option präsentieren, die nicht auf Regex angewiesen ist. – chillysapien

1

Sie dies, indem Sie einfach mit Mustern und Matcher Klasse in Java REGx tun können.

public static String[] mysplit(String text) 
    { 
    List<String> s = new ArrayList<String>(); 
    Matcher m = Pattern.compile("(:|;)\\w+").matcher(text); 
    while(m.find()) { 
    s.add(m.group()); 
    } 
    return s.toArray(new String[s.size()]); 
    } 
+0

Sobald der Regexp Djinni aus der Flasche ist, bevorzuge ich Bozho's Lösung. –

+0

Yup .. ich stimme zu ... oben war nur eine Alternative Art es zu tun :) – Favonius

1
/** 
* @param list an empty String list. used for internal purpose. 
* @param str String which has to be processed. 
* @return Splited String Array with delimiters. 
*/ 
public String[] split(ArrayList<String> list, String str){ 
    for(int i = str.length()-1 ; i >=0 ; i--){ 
    if(!Character.isLetterOrDigit((str.charAt(i)))) { 
     list.add(str.substring(i, str.length())); 
     split(list,str.substring(0,i)); 
     break; 
    } 
    } 
    return list.toArray(new String[list.size()]); 
} 
+1

Dies ist nur eine weitere Möglichkeit! für die, die nicht über Regex wie ich wissen :) –

0

Dies sollte mit Java 1.5 arbeiten (Pattern.quote in Java 1.5 eingeführt wurde).

// Split the string on delimiter, but don't delete the delimiter 
private String[] splitStringOnDelimiter(String text, String delimiter, String safeSequence){ 
    // A temporary delimiter must be added as Java split method deletes the delimiter 

    // for safeSequence use something that doesn't occur in your texts 
    text=text.replaceAll(Pattern.quote(delimiter), safeSequence+delimiter); 
    return text.split(Pattern.quote(safeSequence)); 
} 

Wenn das erste Element ist das Problem:

private String[] splitStringOnDelimiter(String text, String delimiter, String safeSequence){ 
    text=text.replaceAll(Pattern.quote(delimiter), safeSequence+delimiter); 
    String[] tempArray = text.split(Pattern.quote(safeSequence)); 
    String[] returnArray = new String[tempArray.length-1]; 
    System.arraycopy(tempArray, 1, returnArray, 0, returnArray.length); 
    return returnArray; 
} 

Z.B.hier, "a" ist das Trennzeichen:

splitStringOnDelimiter("-asd-asd-g----10-9asdas jadd", "a", "<>") 

Sie diese:

1.: - 
2.: asd- 
3.: asd-g----10-9 
4.: asd 
5.: as j 
6.: add 

Wenn Sie in der Tat diese wollen:

1.: -a 
2.: sd-a 
3.: sd-g----10-9a 
4.: sda 
5.: s ja 
6.: dd 

Sie wechseln:

safeSequence+delimiter 

mit

delimiter+safeSequence 
Verwandte Themen