2010-09-23 8 views

Répondre

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

Ceci vous donnera le tableau désiré, seulement avec un premier élément vide. Et:

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

Cela donnera le tableau sans le premier élément vide.

  • la clé est le (?=X) qui est une anticipation positif de largeur nulle (construction non-capture) ici (voir regex pattern docs).
  • [:;] signifie « soit; ou: »
  • \b est limite de mot - il est là pour ne pas considérer le premier : comme séparateur (puisqu'il est le début de la séquence)
+0

'(? = X)' est "lookahead positif à largeur nulle", le groupe sans capture est '(?: X)'. Cela ne fonctionnerait pas correctement avec le groupe non-capture ... –

+0

@Carlos Heuberger pourriez-vous expliquer plus? Il fonctionne réellement de cette façon (testé), mais j'ai peut-être manqué quelque chose – Bozho

+1

ça marche mais la séquence '(? = X)' n'est pas appelée "groupe non-capturant", ou pas le simple "groupe non-capturant" . Il est appelé "lookahead positive de largeur zéro". Le "groupe non-capturant" est '(?: X)'. (désolé pour mon mauvais anglais) –

4

Pour garder les séparateurs, vous pouvez utiliser un StringTokenizer:

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

Cela produirait les séparateurs en jetons. Pour les inclure dans vos jetons, vous pouvez utiliser String#split avec lookahead.

+3

« StringTokenizer est une classe héritée » – Bozho

+3

@Bozho vrai, mais je pense que cette utilisation particulière le cas de garder les délimiteurs ne sont pas couverts très bien par chaîne #split, qui nécessite quelques connaissances regex détaillées pour l'obtenir. –

+0

vrai, c'est un peu plus clair avec StringTokenizer, car il a l'option désirée en tant que paramètre booléen. +1, le point sur l'héritage est toujours valide. – Bozho

-1

En supposant que vous avez seulement un ensemble fini de séparateurs avant les mots dans votre chaîne (par exemple;,: etc) vous pouvez utiliser la technique suivante. (excuses pour les erreurs de syntaxe, mais sa fait un moment que je Java)

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

c'est plus simple. – Joset

+0

1. Il est incorrect car il renvoie un 0e élément vide. 2. Cela augmente le risque d'erreur dû aux duplications (ie ":" doit être associé à "~:") 3. Que faire si le délimiteur spécial "~" est utilisé dans l'une des sous-chaînes? –

+0

@Tony, j'ai choisi "~" comme exemple, mais n'importe quel autre délimiteur unique pourrait être utilisé qui était approprié à l'ensemble de données disponible. Je ne vois pas vraiment comment cela augmente les risques d'erreur - peut-être pourriez-vous clarifier ce point. J'avoue qu'il laisse un 0e élément vide qui est un échec de cette approche, mais je voulais présenter une autre option qui ne reposait pas sur regex – chillysapien

1

Vous pouvez le faire en utilisant simplement les modèles et la classe matcher en java REGX.

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

Une fois que le djinni regexp est sorti de la bouteille, je préfère la solution de Bozho. –

+0

Yup .. je suis d'accord ... ci-dessus était juste une façon alternative de le faire :) – 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

Ceci est juste un autre moyen! pour qui ne connaît pas regex comme moi :) –

0

Cela devrait fonctionner avec Java 1.5 (Pattern.quote a été introduit en Java 1.5).

// 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)); 
} 

Si le premier élément est le problème:

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; 
} 

Par ex, Ici "a" est le séparateur:

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

Vous obtenez ceci:

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

Si, en fait, vous voulez ceci:

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

Vous passez:

safeSequence+delimiter 

avec

delimiter+safeSequence 
Questions connexes