Cómo dividir una cadena en Java

1640

Tengo una cadena, "004-034556"que quiero dividir en dos cadenas:

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

Eso significa que la primera cadena contendrá los caracteres antes '-', y la segunda cadena contendrá los caracteres después '-'. También quiero verificar si la cadena tiene '-'. Si no, lanzaré una excepción. ¿Cómo puedo hacer esto?

riyana
fuente

Respuestas:

2935

Sólo tiene que utilizar el método apropiado: String#split().

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

Tenga en cuenta que esto toma una expresión regular , así que recuerde escapar de caracteres especiales si es necesario.

Hay 12 caracteres con significados especiales: la barra diagonal inversa \, el ^símbolo de intercalación , el signo de dólar $, el punto o punto ., el símbolo de barra o tubo vertical |, 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 denominan "metacaracteres".

Por lo tanto, si desea dividir, por ejemplo, punto / punto, .que significa " cualquier carácter " en la expresión regular, use una barra diagonal inversa\ para escapar del carácter especial individual como tal split("\\."), o use la clase de caracteres[] para representar caracteres literales como ese split("[.]"), o use Pattern#quote()para escapar de toda la cadena así split(Pattern.quote(".")).

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

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

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

Tenga en cuenta que esto no toma una expresión regular. Para eso, use String#matches()en su lugar.

Si desea conservar el carácter dividido en las partes resultantes, utilice una apariencia positiva . En caso de que desee que el carácter dividido termine en el lado izquierdo, use una mirada hacia atrás positiva al prefijar el ?<=grupo en el patrón.

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

En caso de que desee que el carácter dividido termine en el lado derecho, use una búsqueda positiva al prefijar el ?=grupo en el patrón.

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

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

String string = "004-034556-42";
String[] parts = string.split("-", 2);
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556-42
BalusC
fuente
27
¿Por qué usas símbolos hash para delimitar los métodos de String?
Crowie
94
@Crowie: estilo javadoc.
BalusC
99
Caso de esquina: si no puede encontrarlo reugalr expression, devuelve una matriz de elementos con una cadena completa.
klimat
2
No puedo creer que la versión más votada sea así. 1) parte2 no es lo que el póster quiere si la cadena original contiene dos "-" 2) Sin manejo de errores como se menciona en la pregunta. 3) Baja eficiencia. Una búsqueda de un solo carácter necesita una construcción y coincidencia de expresiones regulares. Matriz adicional creada, etc.
David
1
@David: 1) Eso no está cubierto en la pregunta. 2) No arroja excepciones. 3) OP pregunta cómo dividir, no cómo subcadenas. 4) Tómese un descanso, respire profundamente y deseche toda la negatividad en su cabeza :)
BalusC
79

Una alternativa para procesar la cadena directamente sería usar una expresión regular con grupos de captura. Esto tiene la ventaja de que hace que sea sencillo implicar restricciones más sofisticadas en la entrada. Por ejemplo, lo siguiente divide la cadena en dos partes y garantiza que ambas consistan solo en dígitos:

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

Como el patrón se arregla en este caso, puede compilarse por adelantado y almacenarse como un miembro estático (inicializado en el momento de carga de la clase en el ejemplo). La expresión regular es:

(\d+)-(\d+)

Los paréntesis denotan los grupos de captura; Se puede acceder a la cadena que coincide con esa parte de la expresión regular mediante el método Match.group (), como se muestra. \ D coincide con un solo dígito decimal, y el + significa "coincide con una o más de la expresión anterior). al escribir esto como una cadena de Java. Algunos otros ejemplos:

([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
Rob Hague
fuente
Esta es una gran solución, sin embargo, la primera parte debería ser m.group(1), la segunda parte m.group(2), ya que en m.group(0)realidad devuelve el patrón de coincidencia completo. Creo que también recuerdo que group(0)solía ser la primera coincidencia en lugar del patrón completo, tal vez esto cambió en una actualización reciente de la versión de Java.
ptstone
1
Gracias. Mirando docs.oracle.com/javase/7/docs/api/java/util/regex/… , tiene razón: en línea con la mayoría de las otras bibliotecas de expresiones regulares , el grupo 0 es la coincidencia completa y los grupos capturados comienzan en 1. Como usted dice, sospecho que esto puede haber cambiado desde que originalmente escribí la respuesta, pero en cualquier caso la actualizaré para reflejar el comportamiento actual.
Rob Hague
42
String[] result = yourString.split("-");
if (result.length != 2) 
     throw new IllegalArgumentException("String not in correct format");

Esto dividirá su cadena en 2 partes. El primer elemento en la matriz será la parte que contiene las cosas antes de -, y el segundo elemento en la matriz contendrá la parte de su cadena después de -.

Si la longitud de la matriz no es 2, entonces la cadena no estaba en el formato: string-string.

Echa un vistazo al split()método en la Stringclase.

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

jjnguy
fuente
55
Esto aceptará "-555" como entrada y devolverá [, 555]. Los requisitos no están definidos de manera clara, si sería válido aceptar esto. Recomiendo escribir algunas pruebas unitarias para definir el comportamiento deseado.
Michael Konietzka
Probablemente más seguro para cambiar (result.length! = 2) a (result.length <2)
Tío Iroh
29
String[] out = string.split("-");

deberías hacer lo que quieras. La clase de cadena tiene muchos métodos para operar con cadena.

secmask
fuente
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]);
}
Mnyikka
fuente
6060
El JavaDoc establece claramente: " StringTokenizeres una clase heredada que se retiene por razones de compatibilidad, aunque se desaconseja su uso en el nuevo código . Se recomienda que cualquiera que busque esta funcionalidad utilice el splitmétodo Stringo el java.util.regexpaquete".
bvdb
23

Con Java 8:

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

    stringList.forEach(s -> System.out.println(s));
Somaiah Kumbera
fuente
2
Si desea eliminar espacios en blanco, agregue .map(String::trim)después desplit
Roland
18

Los requisitos dejaron espacio para la interpretación. Recomiendo escribir un método,

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

que encapsulan esta función. Por supuesto, puede usar String.split (..) como se menciona en las otras respuestas para la implementación.

Debe escribir algunas pruebas unitarias para las cadenas de entrada y los resultados y el comportamiento deseados.

Los buenos candidatos para la prueba deben incluir:

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

Con la definición de los resultados de la prueba, puede especificar el comportamiento.

Por ejemplo, si "-333"debería regresar [,333]o si es un error. ¿Se "333-333-33"puede separar [333,333-33] or [333-333,33]o es un error? Y así.

Michael Konietzka
fuente
44
Consejos útiles, pero en realidad no es una respuesta a la pregunta. Si está apoyando otra respuesta con detalles, se prefiere un comentario.
Chris Mountford
Use: split (String regex, int limit) y NOT split (String regex) para referencia visite geeksforgeeks.org/split-string-java-examples
Ryan Augustine
16

Puedes probar así también

 String concatenated_String="hi^Hello";

 String split_string_array[]=concatenated_String.split("\\^");
SHUNMUGA RAJ PRABAKARAN
fuente
16

Asumiendo que

  • realmente no necesitas expresiones regulares para tu división
  • ya usas apache commons lang en tu aplicación

La forma más fácil es usar StringUtils # split (java.lang.String, char) . Eso es más conveniente que el proporcionado por Java fuera de la caja si no necesita expresiones regulares. Como dice su manual, funciona así:

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"]

Recomendaría usar commong-lang, ya que generalmente contiene muchas cosas que se pueden usar. Sin embargo, si no lo necesita para otra cosa que no sea una división, implementarse o escapar de la expresión regular es una mejor opción.

eis
fuente
15

Use el método de división org.apache.commons.lang.StringUtils que puede dividir cadenas en función del carácter o cadena que desea dividir.

Firma del método:

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

En su caso, desea dividir una cadena cuando hay un "-".

Simplemente puede hacer lo siguiente:

String str = "004-034556";

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

Salida:

004
034556

Suponga que si -no existe en su cadena, devuelve la cadena dada y no obtendrá ninguna excepción.

sandeep vanama
fuente
14

Para resumir: hay al menos cinco formas de dividir una cadena en Java:

  1. String.split ():

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

    List<String> strings = Pattern.compile("\\|")
          .splitAsStream("010|020202")
          .collect(Collectors.toList());
  3. StringTokenizer (clase heredada):

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

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

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

Por lo tanto, puede elegir la mejor opción para usted dependiendo de lo que necesite, por ejemplo, tipo de retorno (matriz, lista o iterable).

Aquí hay una gran descripción de estos métodos y los ejemplos más comunes (cómo dividir por punto, barra, signo de interrogación, etc.)

Dmytro Shvechikov
fuente
13

La forma más rápida, que también consume la menor cantidad de recursos podría ser:

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 '-'
}
David
fuente
66
El recurso más escaso es a menudo el tiempo y la atención del programador. Este código consume más de ese recurso que las alternativas.
Chris Mountford
tiene muchos recursos integrados que puede usar, donde el rendimiento realmente se considera, esta solución carece de tiempo de ejecución de rendimiento
J Sanchez
1
Para hacer una división simple en un solo carácter con comprobación de errores, esto no es más complejo que la versión regex.
tekHedd
¡Bravo! ¡Finalmente una respuesta a esta pregunta que no usa regex! Usar una expresión regular para esta tarea simple es más bien un rasguño de cabeza. Es bueno ver que todavía hay programadores sanos en esta tierra :-)
Gabriel Magana
Solo hay un "-", se desea una excepción y el resultado debe ir a string1 y string2. Haz string1 = s.substring(0, s.indexOf("-")); string2 = s.substring(s.indexOf("-") + 1);de eso. Obtendrá el StringIndexOutOfBoundsExceptionautomáticamente si no hubo "-".
Kaplan
13

División de cadenas con múltiples caracteres usando 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]);
        }
     }
  }

Salida:

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

Pero no espere el mismo resultado en todas las versiones de JDK. He visto un error que existe en algunas versiones de JDK donde la primera cadena nula ha sido ignorada. Este error no está presente en la última versión de JDK, pero existe en algunas versiones entre las versiones finales JDK 1.7 y 1.8 versiones anteriores.

Ravindra babu
fuente
13

Para casos de uso simple String.split()debe hacer el trabajo. Si usa guayaba, también hay una clase Splitter que permite el encadenamiento de diferentes operaciones de cadena y admite CharMatcher :

Splitter.on('-')
       .trimResults()
       .omitEmptyStrings()
       .split(string);
Vitalii Fedorenko
fuente
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);
    }
}
Akhilesh Dhar Dubey
fuente
9

Puede dividir una cadena por un salto de línea utilizando la siguiente instrucción:

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

Puede dividir una cadena por un guión / carácter utilizando la siguiente instrucción:

String textStr[] = yourString.split("-");
RajeshVijayakumar
fuente
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]);
    }
  }
}
Ravi Pandey
fuente
44
Si puedo compartir consejos, ¿cómo su respuesta aporta más valor que la solución ya aceptada? stackoverflow.com/a/3481842/420096 en tales situaciones puede votar sobre la solución existente, especialmente si este es un caso trivial claro como ese.
Sombrik
8

Puedes usar 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];
    }
}

De lo contrario, puede usar 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("-");
    }
}
Sarat Chandra
fuente
8

Solo hay dos métodos que realmente debe considerar.

Use String.split para un delimitador de un carácter o no le importa el rendimiento

Si el rendimiento no es un problema, o si el delimitador es un solo carácter que no es un carácter especial de expresión regular (es decir, no es uno de .$|()[{^?*+\), puede usarlo String.split.

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

El método de división tiene una optimización para evitar el uso de una expresión regular si el delímetro es un solo carácter y no está en la lista anterior. De lo contrario, tiene que compilar una expresión regular, y esto no es lo ideal.

Use Pattern.split y precompile el patrón si usa un delimitador complejo y le preocupa el rendimiento.

Si el rendimiento es un problema y su delimitador no es uno de los anteriores, debe precompilar un patrón de expresión regular que luego puede reutilizar.

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

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

Esta última opción todavía crea un nuevo Matcherobjeto. También puede almacenar en caché este objeto y restablecerlo para cada entrada para obtener el máximo rendimiento, pero eso es algo más complicado y no es seguro para subprocesos.

rghome
fuente
7

Una forma de hacerlo es ejecutar la cadena en un bucle for-each y usar el carácter de división requerido.

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

Salida:

The split parts of the String are:
004
034556
Keshav Pradeep Ramanath
fuente
7

No utilice la clase StringTokenizer , ya que es una clase heredada que se conserva por razones de compatibilidad, y su uso no se recomienda en el nuevo código. Y también podemos utilizar el método de división según lo sugerido por otros.

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

Y como se esperaba imprimirá:

[004, 034556]

En esta respuesta, también quiero señalar un cambio que ha tenido lugar para el splitmétodo en Java 8 . El método String # split () utiliza Pattern.split, y ahora eliminará cadenas vacías al comienzo de la matriz de resultados. Observe este cambio en la documentación para Java 8:

Cuando hay una coincidencia de ancho positivo al comienzo de la secuencia de entrada, se incluye una subcadena inicial vacía al comienzo de la matriz resultante. Sin embargo, una coincidencia de ancho cero al principio nunca produce una subcadena inicial tan vacía.

Significa para el siguiente ejemplo:

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

obtendremos tres cadenas: [0, 0, 4]y no cuatro como era el caso en Java 7 y anteriores. También revise esta pregunta similar .

akhil_mittal
fuente
7

Aquí hay dos maneras en que dos lo logran.

CAMINO 1: como debe dividir dos números por un carácter especial, puede usar expresiones regulares

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

CAMINO 2: Usando el método de división de cadenas

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);
        }
    }
}
Akshay Gaikwad
fuente
6

Simplemente puede usar StringTokenizer para dividir una cadena en dos o más partes, ya sea que haya algún tipo de delimitador:

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

Echa un vistazo al split()método en la Stringclase sobre 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++;
}

Aquí hay muchos ejemplos para una cadena dividida pero un pequeño código optimizado.

Divyesh Kanzariya
fuente
Reemplace -con |y vea lo que sucede :)
Dom dom
En ese caso, consulte stackoverflow.com/questions/10796160/…
R dom
4
String str="004-034556"
String[] sTemp=str.split("-");// '-' is a delimiter

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

Solo quería escribir un algoritmo en lugar de usar funciones incorporadas de 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;
}
Ninguna
fuente
1

Puedes usar el método 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 \"-\".");
        }
    }
}
Jamith
fuente
1

Para dividir una cadena, usa String.split (regex). Revise los siguientes ejemplos:

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

Salida

004
034556

Nota:

Esta división (regex) toma una expresión regular como argumento. Recuerde escapar de los caracteres especiales regex, como punto / punto.

KIBOU Hassan
fuente
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));
    }
}

Como mencionan todos, split () es la mejor opción que se puede usar en su caso. Un método alternativo puede ser usar substring ().

SAM Jr
fuente
0

Para dividir una cadena, use String.split(regex):

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

Salida:

004
034556
KIBOU Hassan
fuente