52

A partir de un String, "123-654321", lo que deseo es dividirlo en dos Strings:

string1=123
string2=654321
Jorgesys
  • 103,630
  • 13
  • 52
  • 124
  • 6
    Esto es una "wiki de comunidad", realizada para este proposito: http://meta.es.stackoverflow.com/questions/1320/las-preguntas-con-enlaces-cruzados **Pueden editar la pregunta y la respuesta** agregando más información. – Jorgesys Jan 25 '17 at 01:23
  • 1
    asociación: https://stackoverflow.com/questions/3481828/how-to-split-a-string-in-java – fedorqui Feb 26 '19 at 14:50
  • Te comparto este vídeo donde explican como funciona el método split. https://youtu.be/SksMIGXLCxc – charly0612 Oct 07 '21 at 17:54

7 Answers7

84

Para eso se usa el método String#split() en el cual defines un separador, que en caso de esta String es "-".

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

El método toma como parámetro una expresión regular. Si se quiere utilizar un separador textual, se deben escapar los caracteres \ ^ $ . | ? * + ( ) [ { antecediéndolos con una \.

String[] parts = string.split("\\|"); // Separar por "|"

O se puede utilizar el método Pattern#quote().

String separador = Pattern.quote("|");
String[] parts = string.split(separador);

¿Tienes problemas al usar un caracter como separador?

Existen caracteres para "uso especial" llamados metacaracteres,

Los metacaracteres son caracteres no alfabéticos que poseen un significado especial en las expresiones regulares. que son :

\ , ^ , $ , . , | , ? , * , + , ( , ) , { , } , [

Si estos son usados directamente para separar una cadena no funcionaran adecuadamente, ejemplo:

String cadena = "Hola|Stackoverflow|en|español";
String[] parts = cadena.split("|");              
System.out.println(Arrays.asList(parts));

Salida incorrecta:

[H, o, l, a, |, S, t, a, c, k, o, v, e, r, f, l, o, w, |, e, n, |, e, s, p, a, ñ, o, l]

estos caracteres deben ser escapados antecediendo el caracter "\", ejemplo:

String cadena = "Hola|Stackoverflow|en|español";
String[] parts = cadena.split("\\|");              
System.out.println(Arrays.asList(parts));

Salida correcta:

[Hola, Stackoverflow, en, español]

Para poder aplicar el separador en cualquiera de los casos se puede usar el siguiente método, en el cual se define la cadena y el separador, si detecta que el carácter separador es metacaracter aplica un escape:

private static String[] separaCaracteres(String cadena, String separator){        
    System.out.println("Separator: " + separator);
    String[] parts = null;   
    if(separator.equals("|")|| separator.equals("\\")||separator.equals(".")||separator.equals("^")||separator.equals("$")
            ||separator.equals("?")||separator.equals("*")||separator.equals("+")||separator.equals("(")||separator.equals(")")
            ||separator.equals("{")||separator.equals("[")){
        //Es metacaracter!
        parts = cadena.split("\\"+separator);       
    }else{
        //No es metacaracter.
        parts = cadena.split(separator);
    }    
    return parts;
}

Ejemplo llamando el método anterior:

   System.out.println(Arrays.asList(separaCaracteres("Hola\\Stackoverflow\\en\\español", "\\")).toString());
   System.out.println(Arrays.asList(separaCaracteres("Hola^Stackoverflow^en^español", "^")).toString());
   System.out.println(Arrays.asList(separaCaracteres("Hola$Stackoverflow$en$español", "$")).toString());       
   System.out.println(Arrays.asList(separaCaracteres("Hola.Stackoverflow.en.español", ".")).toString());       
   System.out.println(Arrays.asList(separaCaracteres("Hola|Stackoverflow|en|español", "|")).toString());       
   System.out.println(Arrays.asList(separaCaracteres("Hola?Stackoverflow?en?español", "?")).toString());
   System.out.println(Arrays.asList(separaCaracteres("Hola*Stackoverflow*en*español", "*")).toString());
   System.out.println(Arrays.asList(separaCaracteres("Hola+Stackoverflow+en+español", "+")).toString());
   System.out.println(Arrays.asList(separaCaracteres("Hola(Stackoverflow(en(español", "(")).toString());
   System.out.println(Arrays.asList(separaCaracteres("Hola)Stackoverflow)en)español", ")")).toString());
   System.out.println(Arrays.asList(separaCaracteres("Hola{Stackoverflow{en{español", "{")).toString());
   System.out.println(Arrays.asList(separaCaracteres("Hola}Stackoverflow}en}español", "}")).toString());
   System.out.println(Arrays.asList(separaCaracteres("Hola[Stackoverflow[en[español", "[")).toString());       
   System.out.println(Arrays.asList(separaCaracteres("Hola Stackoverflow en español", " ")).toString());
   System.out.println(Arrays.asList(separaCaracteres("Hola½Stackoverflow½en½español", "½")).toString());
   System.out.println(Arrays.asList(separaCaracteres("Hola-Stackoverflow-en-español", "-")).toString());  

Salida:

Separator: \
[Hola, Stackoverflow, en, español]
Separator: ^
[Hola, Stackoverflow, en, español]
Separator: $
[Hola, Stackoverflow, en, español]
Separator: .
[Hola, Stackoverflow, en, español]
Separator: |
[Hola, Stackoverflow, en, español]
Separator: ?
[Hola, Stackoverflow, en, español]
Separator: *
[Hola, Stackoverflow, en, español]
Separator: +
[Hola, Stackoverflow, en, español]
Separator: (
[Hola, Stackoverflow, en, español]
Separator: )
[Hola, Stackoverflow, en, español]
Separator: {
[Hola, Stackoverflow, en, español]
Separator: }
[Hola, Stackoverflow, en, español]
Separator: [
[Hola, Stackoverflow, en, español]
Separator:  
[Hola, Stackoverflow, en, español]
Separator: ½
[Hola, Stackoverflow, en, español]
Separator: -
[Hola, Stackoverflow, en, español]
Jorgesys
  • 103,630
  • 13
  • 52
  • 124
52

split() es el método

El método más apropiado para dividir una cadena es String#split().

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

No obstante, a la hora de usar split debemos tener en cuenta algunas cosas.


Los caracteres especiales

Al hacer split de cualquier cadena hemos de considerar que éste método toma una expresión regular, por lo que será necesario escapar los caracteres especiales cuando el caso lo amerite.

Hay 12 caracteres con significados especiales: la barra invertida \, el recuadro ^, el signo de dólar $, el punto ., La barra vertical o el símbolo de tubería |, el signo de interrogación ?, el asterisco o la estrella *, el signo más + , el paréntesis de apertura (, el paréntesis de cierre ) y el corchete de apertura [, la llave de apertura {. Estos caracteres especiales a menudo se llaman "metacaracteres". (Ver este enlace)

Por lo tanto, si desea dividir, por ejemplo esta cadena: período/punto, lo cual significa "cualquier carácter" en regex, utilice la barra invertida \ para escapar del carácter especial individual. Algo así: split("\\."), o utilice la clase de caracteres \[\] para representar caracteres literales como split("[.]"), o use Pattern#quote() para escapar de toda la cadena como si fuese split(Pattern.quote (". ")).

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

Se puede hacer una prueba previa

Para probar de antemano si la cadena contiene ciertos caracteres, use String#contains().

if (string.contains("-")) {
    // Hacer split.
} else {
    throw new IllegalArgumentException("String " + string + " no contiene -");
}

Pero este código no toma una expresión regular. Para ello, utilice String#matches() en su lugar.


Conservar el caracter de división en alguna de las partes

Si desea conservar el carácter de división en las partes resultantes, haga uso de la apariencia positiva. En caso de que desee tener el carácter de división en el lado izquierdo del último split, use lookbehind (mirada hacia atrás) positivo prefijando el grupo ?<= en el patrón.

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

En caso de que desee tener el carácter de división al final, en el lado derecho del primer split, use lookahead (mirada hacia adelante) positivo prefijando el grupo ?= en el patrón.

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

Limitar el número de partes resultantes

Si desea limitar el número de partes resultantes, puede proporcionar el número deseado como segundo argumento del método split().

String string = "123-654321-789";
String[] parts = string.split("-", 2);
String part1 = parts[0]; // 123
String part2 = parts[1]; // 654321-789

Cadenas vacías

Hay casos en que los elementos del array String devuelto tienen cadenas en blanco.

  • Prefijo: - cuando la cadena comienza con el delimitador, el primer elemento se convierte en cadena vacía.

    String[] items = ",A,B,C".split(",");
    

Es equivalente a:

    String[] items = { "", "A", "B", "C" };
  • Medio: - cada ocurrencia adicional del delimitador en el medio de la Cadena resultará en una cadena vacía correspondiente:

    String[] items = ",A,B,,,C".split(","); 
    

Es equivalente a:

    String[] items = { "", "A", "B", "", "", "C" };
  • Sufijo: toda la ocurrencia del delimitador al final de la cadena será ignorada.

    String[] items = "A,B,C,,,,,,,,,,".split(","); 
    

Es equivalente a:

    String[] items = { "A", "B", "C" };

Sin embargo, podemos forzar división para contar todos los delimitadores adicionales al final de la cadena pasando -1 como límite:

    String[] items = "A,B,C,,,".split(",", -1); 

Es equivalente a:

    String[] items = { "A", "B", "C", "", "", "" };

Fuentes:

A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • 1
    Excelente, muchas gracias por la respuesta a esta pregunta!. – Jorgesys Jul 28 '17 at 17:28
  • 5
    Gracias @Jorgesys Fíjate que alguien acaba de votar contra esta respuesta sin siquiera dejar una explicación del por qué. – A. Cedano Jul 28 '17 at 21:06
  • 2
    @A.Cedano el voto negativo del *novato* – L. Ronquillo Jul 28 '17 at 21:34
  • mmm es bueno que se agregué un comentario para el voto negativo, (aunque no sea necesario), por cierto es excelente tu respuesta, es lo que alentaba para esta pregunta. – Jorgesys Jul 28 '17 at 22:25
  • 2
    No había leído el enlace de Meta que pones en comentario en la pregunta @Jorgesys. Resulta que actualmente tenemos en castellano una respuesta más completa que en inglés, ya que he agregado al final lo que ocurre con las cadenas vacías. La propuesta en el meta me parece una excelente idea. Lo que no queda muy claro es si es mejor una sola respuesta Wiki de comunidad, o varias respuestas. – A. Cedano Jul 29 '17 at 16:28
14

Tres formas diferentes de hacerlo:

1. Utilizando la función String.split() :

 String str = "123-654321";
 String[] parts = str.split("-");

Esta solución utiliza expresiones regulares, así que no es lo más eficiente si no estas trabajando con ellas.


2. Utilizando la clase StringTokenizer :
static private List<String> fastSplit(final String text, final String separator, final boolean emptyStrings){
    List<String> result = new ArrayList<String>();
    final StringTokenizer st = new StringTokenizer(text, separator, true);
    String token = null;
    String lastToken = separator;
    while (st.hasMoreTokens()) {
            token = st.nextToken();
            if (token.equals(separator)) {
                    if (lastToken.equals(separator) && emptyStrings) {
                            result.add("");
                    }
            } else {
                    result.add(token);
            }
            lastToken = token;
    }

    return result;
}

El problema con este método es que solo funciona bien cuando el delimitador tiene longitud 1.


3. Implementarlo usando String.indexOf() :

En este caso si funcionará correctamente para delimitadores de cualquier longitud.

static private List<String> fastSplit2(final String text, final String separator, final boolean emptyStrings) {
    final List<String> result = new ArrayList<String>();

    if (text != null && text.length() > 0) {
        int index1 = 0;
        int index2 = text.indexOf(separator);
        int sepLen = separator.length();
        while (index2 >= 0) {
            String token = text.substring(index1, index2);
            if (!token.isEmpty() || emptyStrings){
                result.add(token);
            }
            index1 = index2 + sepLen;
            index2 = text.indexOf(separator, index1);
        }

        if (index1 < text.length() - 1) {
            result.add(text.substring(index1));
        }
    }

    return result;
}
Atscub
  • 545
  • 4
  • 13
10

Usando StringTokenizer: en el constructor de tal detallamos el delimitador "-", new StringTokenizer(nombre,"-");

import java.util.StringTokenizer; 
    public class Separador
    {
      public static void main(String[] args)
      {

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

      }
    }
userStack
  • 6,330
  • 3
  • 20
  • 41
  • 2
    Si bien todavía se puede usar esta clase y no se marca como depreciada, se aconseja no usarla en la generación de código para nuevas aplicaciones. Fuente: [`java.util.StringTokenizer`](https://docs.oracle.com/javase/8/docs/api/java/util/StringTokenizer.html): "`StringTokenizer` is a legacy class that is retained for compatibility reasons although its use is discouraged in new code." De todos modos, es otra forma de conseguir la separación de cadenas. –  Jan 25 '17 at 12:11
8

split() método de división de cadenas() String

Este método tiene dos variantes y divide esta cadena alrededor de las coincidencias de la expresión regular dada.

La sintaxis de este método seria:

public String[] split(String regex)

Detalle de los parámetros:

Regex - la expresión regular delimitadora.

Valor de retorno

Devuelve la matriz de cadenas calculada dividiendo esta cadena en torno a las coincidencias de la expresión regular dada.

Ejemplo

import java.io.*;
public class Test {

   public static void main(String args[]) {
      String Str = new String("123-654321");
      System.out.println("Return Value :" );      

      for (String retval: Str.split("-")) {
         System.out.println(retval);
      }
   }
}

Esto producirá el siguiente resultado:

Salida
Return Value :
123
654321
SoftMolina
  • 1,706
  • 2
  • 9
  • 19
7

Lo que puedes hacer es usar el metodo substring, es decir, extraer ciertos caracteres por su posición o rango de posiciones.

    String cadena = "004-034556";
    String sCadena = cadena.substring(0,3);
    String sCadenaD = cadena.substring(4, cadena.length());
    System.out.println(sCadena);
    System.out.println(sCadenaD);

Si ese no es el único formato que utilizas, puedes usar el metodo indexOf, que te va a servir para extraer todo lo que viene después del guión.

    int guion = cadena.indexOf("-");
    System.out.println(guion);
    String ej = cadena.substring(guion+1, cadena.length());

Espero te sea de ayuda, este es un ejemplo de lo que hice yo con esa misma cadena

public class main{
public static void main (String [] args){
    String cadena = "004-034556";
    String sCadena = cadena.substring(0,3);
    String sCadenaD = cadena.substring(4, cadena.length());
    System.out.println(sCadena);
    System.out.println(sCadenaD);
    int guion = cadena.indexOf("-");
    System.out.println(guion);
    String ej = cadena.substring(guion+1, cadena.length());
    System.out.println(ej);
}        }
Kenny Barrera
  • 2,075
  • 3
  • 22
  • 38
2

Es importante tener en cuenta que al realizar el .split() el primer elemento empieza en [0]

String value= "123-654321";
String[] parts = value.split("-");

System.out.println(parts[0]); //out --> 123

Si el resultado no es conseguido por el separador, la posición [0] será igual al string original

String value= "123-654321";
String[] parts = value.split("p");

System.out.println(parts[0]); //out --> 123-654321