Comment diviser une chaîne en Java


1642

J'ai une chaîne, "004-034556"que je souhaite diviser en deux chaînes:

string1="004";
string2="034556";

Cela signifie que la première chaîne contiendra les caractères avant '-'et la deuxième chaîne contiendra les caractères après '-'. Je veux également vérifier si la chaîne en contient '-'. Sinon, je lèverai une exception. Comment puis-je faire ceci?

Réponses:


2937

Il suffit d' utiliser la méthode appropriée: String#split().

String string = "004-034556";
String[] parts = string.split("-");
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556

Notez que cela prend une expression régulière , pensez donc à échapper les caractères spéciaux si nécessaire.

il y a 12 caractères avec des significations spéciales: la barre oblique inverse \, le ^signe d' insertion , le signe dollar $, la période ou le point ., la barre verticale ou le symbole de la pipe |, le point d'interrogation ?, l'astérisque ou l'étoile *, le signe plus +, la parenthèse ouvrante (, la parenthèse fermante ), et le crochet ouvrant [, l'accolade ouvrante {, Ces caractères spéciaux sont souvent appelés "métacaractères".

Donc, si vous voulez diviser par exemple période / point .qui signifie " n'importe quel caractère " dans l'expression régulière, utilisez soit une barre oblique inversée\ pour échapper au caractère spécial individuel comme tel split("\\."), soit utilisez la classe de caractères[] pour représenter des caractères littéraux comme tels split("[.]"), ou utilisez Pattern#quote()pour échapper à la chaîne entière comme ça split(Pattern.quote(".")).

String[] parts = string.split(Pattern.quote(".")); // Split on period.

Pour tester au préalable si la chaîne contient certains caractères, utilisez simplement String#contains().

if (string.contains("-")) {
    // Split it.
} else {
    throw new IllegalArgumentException("String " + string + " does not contain -");
}

Notez que cela ne prend pas d'expression régulière. Pour cela, utilisez String#matches()plutôt.

Si vous souhaitez conserver le caractère scindé dans les parties résultantes, utilisez la recherche positive . Dans le cas où vous souhaitez que le caractère divisé se retrouve dans la partie gauche, utilisez le lookbehind positif en préfixant le ?<=groupe sur le motif.

String string = "004-034556";
String[] parts = string.split("(?<=-)");
String part1 = parts[0]; // 004-
String part2 = parts[1]; // 034556

Dans le cas où vous souhaitez que le caractère divisé se retrouve dans le côté droit, utilisez l'anticipation positive en préfixant le ?=groupe sur le motif.

String string = "004-034556";
String[] parts = string.split("(?=-)");
String part1 = parts[0]; // 004
String part2 = parts[1]; // -034556

Si vous souhaitez limiter le nombre de pièces résultantes, vous pouvez fournir le nombre souhaité comme 2ème argument de la split()méthode.

String string = "004-034556-42";
String[] parts = string.split("-", 2);
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556-42

27
Pourquoi utilisez-vous des symboles de hachage pour délimiter les méthodes de String?
Crowie

94
@Crowie: style javadoc.
BalusC

9
Cas d'angle: s'il ne le trouve pas, reugalr expressionil renvoie un tableau d'éléments avec une chaîne entière.
klimat

2
Je ne peux pas croire que la version la plus votée soit comme ça. 1) la partie 2 n'est pas ce que l'affiche veut si la chaîne d'origine contient deux "-" 2) Pas de gestion d'erreur comme mentionné dans la question. 3) Faible efficacité. Une recherche sur un seul caractère nécessite une construction d'expression régulière et une correspondance. Tableau supplémentaire créé, etc.
David

1
@David: 1) Ce n'est pas couvert dans la question. 2) Il ne lève pas d'exceptions. 3) OP demande comment diviser, pas comment sous-chaîne. 4) Faites une pause, respirez profondément et détruisez toute la négativité dans votre tête :)
BalusC

79

Une alternative au traitement direct de la chaîne serait d'utiliser une expression régulière avec des groupes de capture. Cela a l'avantage de permettre d'impliquer des contraintes plus sophistiquées sur l'entrée. Par exemple, ce qui suit divise la chaîne en deux parties et garantit que les deux ne sont constitués que de chiffres:

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

class SplitExample
{
    private static Pattern twopart = Pattern.compile("(\\d+)-(\\d+)");

    public static void checkString(String s)
    {
        Matcher m = twopart.matcher(s);
        if (m.matches()) {
            System.out.println(s + " matches; first part is " + m.group(1) +
                               ", second part is " + m.group(2) + ".");
        } else {
            System.out.println(s + " does not match.");
        }
    }

    public static void main(String[] args) {
        checkString("123-4567");
        checkString("foo-bar");
        checkString("123-");
        checkString("-4567");
        checkString("123-4567-890");
    }
}

Comme le modèle est fixe dans cette instance, il peut être compilé à l'avance et stocké en tant que membre statique (initialisé au moment du chargement de la classe dans l'exemple). L'expression régulière est:

(\d+)-(\d+)

Les parenthèses indiquent les groupes de capture; la chaîne qui correspond à cette partie de l'expression rationnelle est accessible par la méthode Match.group (), comme indiqué. Le \ d correspond à un seul chiffre décimal, et le + signifie "correspondre à une ou plusieurs des expressions précédentes). Le - n'a pas de signification particulière, donc correspond simplement à ce caractère dans l'entrée. Notez que vous devez double-échapper les barres obliques inverses lors de l'écriture en tant que chaîne Java. Quelques autres exemples:

([A-Z]+)-([A-Z]+)          // Each part consists of only capital letters 
([^-]+)-([^-]+)            // Each part consists of characters other than -
([A-Z]{2})-(\d+)           // The first part is exactly two capital letters,
                           // the second consists of digits

C'est une excellente solution, mais la première partie devrait être m.group(1), la deuxième partie m.group(2), car m.group(0)retourne en fait le modèle de correspondance complet. Je pense que je me souviens également group(0)d'être le premier match au lieu du motif complet, peut-être que cela a changé dans une récente mise à jour de la version java.
ptstone

1
Merci. En regardant docs.oracle.com/javase/7/docs/api/java/util/regex/… , vous avez raison - conformément à la plupart des autres bibliothèques d'expressions rationnelles, le groupe 0 est la correspondance complète et les groupes capturés commencent à 1. Comme vous le dites, je soupçonne que cela a peut-être changé depuis que j'ai écrit la réponse à l'origine, mais en tout cas je vais la mettre à jour pour refléter le comportement actuel.
Rob Hague

42
String[] result = yourString.split("-");
if (result.length != 2) 
     throw new IllegalArgumentException("String not in correct format");

Cela divisera votre chaîne en 2 parties. Le premier élément du tableau sera la partie contenant les éléments avant le -, et le 2e élément du tableau contiendra la partie de votre chaîne après le -.

Si la longueur du tableau n'est pas 2, la chaîne n'a pas été dans le format: string-string.

Découvrez la split()méthode dans la Stringclasse.

https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#split-java.lang.String-int-


5
Cela acceptera "-555" comme entrée et renvoie [, 555]. Les exigences ne sont pas définies de façon aussi claire, s'il serait valable de les accepter. Je recommande d'écrire quelques tests unitaires pour définir le comportement souhaité.
Michael Konietzka

Probly le plus sûr de changer (result.length! = 2) en (result.length <2)
Uncle Iroh

29
String[] out = string.split("-");

devrait faire ce que vous voulez. La classe String possède de nombreuses méthodes pour fonctionner avec la chaîne.


29
// This leaves the regexes issue out of question
// But we must remember that each character in the Delimiter String is treated
// like a single delimiter        

public static String[] SplitUsingTokenizer(String subject, String delimiters) {
   StringTokenizer strTkn = new StringTokenizer(subject, delimiters);
   ArrayList<String> arrLis = new ArrayList<String>(subject.length());

   while(strTkn.hasMoreTokens())
      arrLis.add(strTkn.nextToken());

   return arrLis.toArray(new String[0]);
}

60
Le JavaDoc indique clairement: " StringTokenizerest une classe héritée qui est conservée pour des raisons de compatibilité, bien que son utilisation soit déconseillée dans le nouveau code . Il est recommandé que toute personne recherchant cette fonctionnalité utilise la splitméthode Stringou le java.util.regexpackage à la place."
bvdb

23

Avec Java 8:

    List<String> stringList = Pattern.compile("-")
            .splitAsStream("004-034556")
            .collect(Collectors.toList());

    stringList.forEach(s -> System.out.println(s));

2
Si vous souhaitez supprimer les espaces ajoutés .map(String::trim)après lesplit
Roland

18

Les exigences laissaient place à l'interprétation. Je recommande d'écrire une méthode,

public final static String[] mySplit(final String s)

qui encapsulent cette fonction. Bien sûr, vous pouvez utiliser String.split (..) comme mentionné dans les autres réponses pour l'implémentation.

Vous devez écrire des tests unitaires pour les chaînes d'entrée et les résultats et comportements souhaités.

Les bons candidats aux tests doivent comprendre:

 - "0022-3333"
 - "-"
 - "5555-"
 - "-333"
 - "3344-"
 - "--"
 - ""
 - "553535"
 - "333-333-33"
 - "222--222"
 - "222--"
 - "--4555"

En définissant les résultats de test correspondants, vous pouvez spécifier le comportement.

Par exemple, si "-333"doit revenir [,333]ou s'il s'agit d'une erreur. Peut "333-333-33"être séparé [333,333-33] or [333-333,33]ou est-ce une erreur? Etc.


4
Des conseils utiles, mais pas vraiment une réponse à la question. Si vous soutenez une autre réponse avec des détails, un commentaire est préférable.
Chris Mountford

Utilisation: split (regex de chaîne, limite int) et NOT split (regex de chaîne) pour référence, visitez geeksforgeeks.org/split-string-java-examples
Ryan Augustine

16

Vous pouvez essayer comme ça aussi

 String concatenated_String="hi^Hello";

 String split_string_array[]=concatenated_String.split("\\^");

16

En admettant que

  • vous n'avez pas vraiment besoin d'expressions régulières pour votre séparation
  • vous utilisez déjà apache commons lang dans votre application

Le moyen le plus simple consiste à utiliser StringUtils # split (java.lang.String, char) . C'est plus pratique que celui fourni par Java hors de la boîte si vous n'avez pas besoin d'expressions régulières. Comme son manuel l'indique, il fonctionne comme ceci:

A null input String returns null.

 StringUtils.split(null, *)         = null
 StringUtils.split("", *)           = []
 StringUtils.split("a.b.c", '.')    = ["a", "b", "c"]
 StringUtils.split("a..b.c", '.')   = ["a", "b", "c"]
 StringUtils.split("a:b:c", '.')    = ["a:b:c"]
 StringUtils.split("a b c", ' ')    = ["a", "b", "c"]

Je recommanderais d'utiliser commong-lang, car il contient généralement beaucoup de choses utilisables. Cependant, si vous n'en avez pas besoin pour autre chose que de faire un fractionnement, alors vous implémenter ou échapper à l'expression régulière est une meilleure option.


15

Utilisez la méthode de fractionnement org.apache.commons.lang.StringUtils qui peut fractionner des chaînes en fonction du caractère ou de la chaîne que vous souhaitez fractionner.

Signature de la méthode:

public static String[] split(String str, char separatorChar);

Dans votre cas, vous souhaitez diviser une chaîne lorsqu'il y a un "-".

Vous pouvez simplement faire comme suit:

String str = "004-034556";

String split[] = StringUtils.split(str,"-");

Production:

004
034556

Supposons que si -n'existe pas dans votre chaîne, il renvoie la chaîne donnée et vous n'obtiendrez aucune exception.


14

Pour résumer: il existe au moins cinq façons de diviser une chaîne en Java:

  1. String.split ():

    String[] parts ="10,20".split(",");
  2. Pattern.compile (regexp) .splitAsStream (entrée):

    List<String> strings = Pattern.compile("\\|")
          .splitAsStream("010|020202")
          .collect(Collectors.toList());
  3. StringTokenizer (classe héritée):

    StringTokenizer strings = new StringTokenizer("Welcome to EXPLAINJAVA.COM!", ".");
    while(strings.hasMoreTokens()){
        String substring = strings.nextToken();
        System.out.println(substring);
    }
  4. Google Guava Splitter:

    Iterable<String> result = Splitter.on(",").split("1,2,3,4");
  5. Apache Commons StringUtils:

    String[] strings = StringUtils.split("1,2,3,4", ",");

Vous pouvez donc choisir la meilleure option pour vous en fonction de ce dont vous avez besoin, par exemple le type de retour (tableau, liste ou itérable).

Voici un grand aperçu de ces méthodes et des exemples les plus courants (comment diviser par point, barre oblique, point d'interrogation, etc.)


13

Le moyen le plus rapide, qui consomme également le moins de ressources, pourrait être:

String s = "abc-def";
int p = s.indexOf('-');
if (p >= 0) {
    String left = s.substring(0, p);
    String right = s.substring(p + 1);
} else {
  // s does not contain '-'
}

6
La ressource la plus rare est souvent le temps et l'attention du programmeur. Ce code consomme plus de cette ressource que les alternatives.
Chris Mountford

vous avez beaucoup de ressources intégrées que vous pouvez utiliser, là où les performances sont vraiment prises en compte, cette solution manque de temps d'exécution des performances
J Sanchez

1
Pour effectuer une division simple sur un seul caractère avec vérification des erreurs, ce n'est pas plus complexe que la version regex.
tekHedd

Bravo! Enfin une réponse à cette question qui n'utilise pas regex! L'utilisation d'une expression régulière pour cette tâche simple est plutôt un accroche-tête. C'est bien de voir qu'il y a encore des programmeurs sensés sur cette terre :-)
Gabriel Magana

Il n'y a qu'un "-", une exception est souhaitée et le résultat doit aller à string1 et string2. Faites- string1 = s.substring(0, s.indexOf("-")); string2 = s.substring(s.indexOf("-") + 1);en. Vous obtiendrez StringIndexOutOfBoundsExceptionautomatiquement s'il n'y avait pas de "-".
Kaplan

13

Split de chaîne avec plusieurs caractères à l'aide de Regex

public class StringSplitTest {
     public static void main(String args[]) {
        String s = " ;String; String; String; String, String; String;;String;String; String; String; ;String;String;String;String";
        //String[] strs = s.split("[,\\s\\;]");
        String[] strs = s.split("[,\\;]");
        System.out.println("Substrings length:"+strs.length);
        for (int i=0; i < strs.length; i++) {
            System.out.println("Str["+i+"]:"+strs[i]);
        }
     }
  }

Production:

Substrings length:17
Str[0]:
Str[1]:String
Str[2]: String
Str[3]: String
Str[4]: String
Str[5]: String
Str[6]: String
Str[7]:
Str[8]:String
Str[9]:String
Str[10]: String
Str[11]: String
Str[12]:
Str[13]:String
Str[14]:String
Str[15]:String
Str[16]:String

Mais ne vous attendez pas à la même sortie sur toutes les versions JDK. J'ai vu un bogue qui existe dans certaines versions de JDK où la première chaîne nulle a été ignorée. Ce bogue n'est pas présent dans la dernière version de JDK, mais il existe dans certaines versions entre les dernières versions de JDK 1.7 et les premières versions 1.8.


13

Pour des cas d'utilisation simples String.split()devraient faire le travail. Si vous utilisez la goyave, il existe également une classe Splitter qui permet de chaîner différentes opérations de chaîne et prend en charge CharMatcher :

Splitter.on('-')
       .trimResults()
       .omitEmptyStrings()
       .split(string);

10
public class SplitTest {

    public static String[] split(String text, String delimiter) {
        java.util.List<String> parts = new java.util.ArrayList<String>();

        text += delimiter;

        for (int i = text.indexOf(delimiter), j=0; i != -1;) {
            String temp = text.substring(j,i);
            if(temp.trim().length() != 0) {
                parts.add(temp);
            }
            j = i + delimiter.length();
            i = text.indexOf(delimiter,j);
        }

        return parts.toArray(new String[0]);
    }


    public static void main(String[] args) {
        String str = "004-034556";
        String delimiter = "-";
        String result[] = split(str, delimiter);
        for(String s:result)
            System.out.println(s);
    }
}

9

Vous pouvez fractionner une chaîne par un saut de ligne à l'aide de l'instruction suivante:

String textStr[] = yourString.split("\\r?\\n");

Vous pouvez fractionner une chaîne par un trait d'union / caractère à l'aide de l'instruction suivante:

String textStr[] = yourString.split("-");

9
import java.io.*;

public class BreakString {

  public static void main(String args[]) {

    String string = "004-034556-1234-2341";
    String[] parts = string.split("-");

    for(int i=0;i<parts.length;i++) 
      System.out.println(parts[i]);
    }
  }
}

4
si je peux partager des conseils, comment votre réponse apporte plus de valeur que la solution déjà acceptée? stackoverflow.com/a/3481842/420096 sur de telles situations, vous pouvez voter sur la solution existante, surtout s'il s'agit d'un cas trivial clair comme celui-ci.
Sombriks

8

Vous pouvez utiliser Split ():

import java.io.*;

public class Splitting
{

    public static void main(String args[])
    {
        String Str = new String("004-034556");
        String[] SplittoArray = Str.split("-");
        String string1 = SplittoArray[0];
        String string2 = SplittoArray[1];
    }
}

Sinon, vous pouvez utiliser StringTokenizer:

import java.util.*;
public class Splitting
{
    public static void main(String[] args)
    {
        StringTokenizer Str = new StringTokenizer("004-034556");
        String string1 = Str.nextToken("-");
        String string2 = Str.nextToken("-");
    }
}

8

Il n'y a que deux méthodes à considérer.

Utilisez String.split pour un délimiteur à un caractère ou vous ne vous souciez pas des performances

Si les performances ne sont pas un problème, ou si le délimiteur est un caractère unique qui n'est pas un caractère spécial d'expression régulière (c'est-à-dire pas l'un des .$|()[{^?*+\), vous pouvez utiliser String.split.

String[] results = input.split(",");

La méthode de fractionnement a une optimisation pour éviter d'utiliser une expression régulière si le délimiteur est un seul caractère et ne figure pas dans la liste ci-dessus. Sinon, il doit compiler une expression régulière, ce qui n'est pas idéal.

Utilisez Pattern.split et précompilez le modèle si vous utilisez un délimiteur complexe et que vous vous souciez des performances.

Si les performances sont un problème et que votre délimiteur n'est pas l'un des précédents, vous devez précompiler un modèle d'expression régulière que vous pouvez ensuite réutiliser.

// Save this somewhere
Pattern pattern = Pattern.compile("[,;:]");

/// ... later
String[] results = pattern.split(input);

Cette dernière option crée toujours un nouvel Matcherobjet. Vous pouvez également mettre en cache cet objet et le réinitialiser pour chaque entrée pour des performances maximales, mais cela est un peu plus compliqué et non thread-safe.


7

Une façon de procéder consiste à parcourir la chaîne dans une boucle pour chaque et à utiliser le caractère de fractionnement requis.

public class StringSplitTest {

    public static void main(String[] arg){
        String str = "004-034556";
        String split[] = str.split("-");
        System.out.println("The split parts of the String are");
        for(String s:split)
        System.out.println(s);
    }
}

Production:

The split parts of the String are:
004
034556

7

Veuillez ne pas utiliser la classe StringTokenizer car c'est une classe héritée qui est conservée pour des raisons de compatibilité, et son utilisation est déconseillée dans le nouveau code. Et nous pouvons également utiliser la méthode de fractionnement comme suggéré par d'autres.

String[] sampleTokens = "004-034556".split("-");
System.out.println(Arrays.toString(sampleTokens));

Et comme prévu, il imprimera:

[004, 034556]

Dans cette réponse, je tiens également à souligner un changement qui a eu lieu pour la splitméthode dans Java 8 . La méthode String # split () utilise Pattern.split, et maintenant elle supprimera les chaînes vides au début du tableau de résultats. Notez ce changement dans la documentation de Java 8:

Lorsqu'il existe une correspondance de largeur positive au début de la séquence d'entrée, une sous-chaîne de début vide est incluse au début du tableau résultant. Une correspondance de largeur nulle au début ne produit cependant jamais une telle sous-chaîne de début vide.

Cela signifie pour l'exemple suivant:

String[] sampleTokensAgain = "004".split("");
System.out.println(Arrays.toString(sampleTokensAgain));

nous obtiendrons trois chaînes: [0, 0, 4]et non quatre comme c'était le cas en Java 7 et avant. Vérifiez également cette question similaire .


7

Voici deux façons dont deux y parviennent.

VOIE 1: Comme vous devez diviser deux nombres par un caractère spécial, vous pouvez utiliser l'expression régulière

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

public class TrialClass
{
    public static void main(String[] args)
    {
        Pattern p = Pattern.compile("[0-9]+");
        Matcher m = p.matcher("004-034556");

        while(m.find())
        {
            System.out.println(m.group());
        }
    }
}

WAY 2: Utilisation de la méthode de partage des chaînes

public class TrialClass
{
    public static void main(String[] args)
    {
        String temp = "004-034556";
        String [] arrString = temp.split("-");
        for(String splitString:arrString)
        {
            System.out.println(splitString);
        }
    }
}

6

Vous pouvez simplement utiliser StringTokenizer pour diviser une chaîne en deux ou plusieurs parties, qu'il existe des délimiteurs:

StringTokenizer st = new StringTokenizer("004-034556", "-");
while(st.hasMoreTokens())
{
    System.out.println(st.nextToken());
}

4

Découvrez la split()méthode dans la Stringclasse sur javadoc.

https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String)

String data = "004-034556-1212-232-232";
int cnt = 1;
for (String item : data.split("-")) {
        System.out.println("string "+cnt+" = "+item);
        cnt++;
}

Voici de nombreux exemples de split string mais j'ai peu de code optimisé.


Remplacez -par |et voyez ce qui se passe :)
R dim


4
String str="004-034556"
String[] sTemp=str.split("-");// '-' is a delimiter

string1=004 // sTemp[0];
string2=034556//sTemp[1];

3

Je voulais juste écrire un algorithme au lieu d'utiliser des fonctions intégrées Java:

public static List<String> split(String str, char c){
    List<String> list = new ArrayList<>();
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < str.length(); i++){
        if(str.charAt(i) != c){
            sb.append(str.charAt(i));
        }
        else{
            if(sb.length() > 0){
                list.add(sb.toString());
                sb = new StringBuilder();
            }
        }
    }

    if(sb.length() >0){
        list.add(sb.toString());
    }
    return list;
}

1

Vous pouvez utiliser la méthode split:

public class Demo {
    public static void main(String args[]) {
        String str = "004-034556";

        if ((str.contains("-"))) {
            String[] temp = str.split("-");
            for (String part:temp) {
                System.out.println(part);
            }
        }
        else {
            System.out.println(str + " does not contain \"-\".");
        }
    }
}

1

Pour diviser une chaîne, utilise String.split (regex). Consultez les exemples suivants:

String data = "004-034556";
String[] output = data.split("-");
System.out.println(output[0]);
System.out.println(output[1]);

Production

004
034556

Remarque:

Cette scission (regex) prend un regex comme argument. N'oubliez pas d'échapper aux caractères spéciaux regex, comme point / point.


0
String s="004-034556";
for(int i=0;i<s.length();i++)
{
    if(s.charAt(i)=='-')
    {
        System.out.println(s.substring(0,i));
        System.out.println(s.substring(i+1));
    }
}

Comme mentionné par tout le monde, split () est la meilleure option qui peut être utilisée dans votre cas. Une autre méthode peut être d'utiliser substring ().


0

Pour diviser une chaîne, utilisez String.split(regex):

String phone = "004-034556";
String[] output = phone.split("-");
System.out.println(output[0]);
System.out.println(output[1]);

Production:

004
034556
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.