Como dividir uma string em Java


1640

Eu tenho uma string, "004-034556"que eu quero dividir em duas strings:

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

Isso significa que a primeira string conterá os caracteres antes '-'e a segunda string conterá os caracteres depois '-'. Também quero verificar se a string está '-'nela. Caso contrário, lançarei uma exceção. Como posso fazer isso?

Respostas:


2935

Basta usar o método apropriado: String#split().

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

Observe que isso exige uma expressão regular ; lembre-se de escapar de caracteres especiais, se necessário.

existem 12 caracteres com significados especiais: a barra invertida \, o ^sinal de intercalação , o sinal de dólar $, o ponto ou o ponto ., o símbolo vertical da barra ou tubo |, o ponto de interrogação ?, o asterisco ou estrela *, o sinal de mais +, o parêntese de abertura (, o parêntese de fechamento ), e o colchete de abertura [, o colchete de abertura {. Esses caracteres especiais geralmente são chamados de "metacaracteres".

Portanto, se você deseja dividir, por exemplo, ponto / ponto .que significa " qualquer caractere " na expressão regular, use a barra invertida\ para escapar do caractere especial individual como tal split("\\.")ou use a classe de caractere[] para representar o (s) caractere (s) literal (s) dessa forma split("[.]")ou use Pattern#quote()para escapar da corda inteira assim split(Pattern.quote(".")).

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

Para testar antecipadamente se a string contém certos caracteres, use String#contains().

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

Observe que isso não requer uma expressão regular. Para isso, use em String#matches()vez disso.

Se você deseja manter o caractere dividido nas partes resultantes, use uma pesquisa positiva . Caso você queira que o caractere de divisão termine no lado esquerdo, use um look positivo por trás, prefixando o ?<=grupo no padrão.

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

Caso você deseje que o caractere dividido termine no lado direito, use um visual positivo, prefixando o ?=grupo no padrão.

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

Se você deseja limitar o número de partes resultantes, pode fornecer o número desejado como o segundo argumento do split()método.

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

27
Por que você usa símbolos de hash para delimitar os métodos de String?
Crowie

94
@Crowie: estilo javadoc.
BalusC

9
Caixa de canto: se não conseguir encontrar reugalr expression, retorna um array de elementos com toda a string.
Klimat # 23/16

2
Não posso acreditar que a versão mais votada é assim. 1) parte2 não é o que o pôster deseja se a sequência original contiver dois "-" 2) Nenhum tratamento de erros, conforme mencionado na pergunta. 3) Baixa eficiência. Uma pesquisa de caracteres únicos precisa de construção e correspondência de expressão regular. Matriz extra criada, etc.
David

1
@ David: 1) Isso não é coberto na pergunta. 2) Não gera exceções. 3) O OP pergunta como dividir, não como substring. 4) Faça uma pausa, respire profundamente e lixo toda a negatividade em sua cabeça :)
BalusC

79

Uma alternativa ao processamento direto da string seria usar uma expressão regular com grupos de captura. Isso tem a vantagem de facilitar a implicação de restrições mais sofisticadas na entrada. Por exemplo, o seguinte divide a sequência em duas partes e garante que ambas consistam apenas em 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 o padrão é corrigido nesta instância, ele pode ser compilado com antecedência e armazenado como um membro estático (inicializado no tempo de carregamento da classe no exemplo). A expressão regular é:

(\d+)-(\d+)

Os parênteses indicam os grupos de captura; a sequência que corresponde a essa parte da regexp pode ser acessada pelo método Match.group (), conforme mostrado. O \ d corresponde a um dígito decimal único e o + significa "corresponde a uma ou mais da expressão anterior). O - não tem significado especial; portanto, apenas corresponde ao caractere na entrada. Observe que você precisa escapar duas vezes as barras invertidas ao escrever isso como uma string Java. Alguns outros exemplos:

([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

Esta é uma ótima solução, no entanto, a primeira parte deve ser m.group(1)a segunda parte m.group(2), pois m.group(0)na verdade retorna o padrão de correspondência completa. Eu acho que também me lembro que group(0)costumava ser a primeira partida em vez do padrão completo, talvez isso tenha sido alterado em uma atualização recente da versão java.
ptstone

1
Obrigado. Olhando para docs.oracle.com/javase/7/docs/api/java/util/regex/… , você está certo - alinhado com a maioria das outras bibliotecas regexp, o grupo 0 é a correspondência completa e os grupos capturados começam em 1. Como você diz, suspeito que isso possa ter mudado desde que escrevi a resposta originalmente, mas, em qualquer caso, eu a atualizarei para refletir o comportamento atual.
Rob Hague

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

Isso dividirá sua string em 2 partes. O primeiro elemento da matriz será a parte que contém o material antes da -, e o segundo elemento da matriz conterá a parte da sua sequência após a -.

Se o comprimento da matriz não é 2, então a cadeia não estava no formato: string-string.

Confira o split()método na Stringclasse.

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


5
Isso aceitará "-555" como entrada e retornará [, 555]. Os requisitos não estão definidos de maneira clara, se seria válido aceitar isso. Eu recomendo escrever alguns testes de unidade para definir o comportamento desejado.
22910 Michael Michaelietietka

Probly mais segura de mudança (! Result.length = 2) a (result.length <2)
Uncle Iroh

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

deve fazer o que quiser. A classe String possui muitos métodos para operar com string.


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
O JavaDoc afirma claramente: " StringTokenizeré uma classe herdada que é mantida por motivos de compatibilidade, embora seu uso seja desencorajado em novo código . É recomendável que qualquer pessoa que procure essa funcionalidade use o splitmétodo Stringou o java.util.regexpacote".
bvdb

23

Com o Java 8:

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

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

2
Se você deseja remover o espaço em branco adicione .map(String::trim)após osplit
Roland

18

Os requisitos deixaram espaço para interpretação. Eu recomendo escrever um método,

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

que encapsula essa função. Obviamente, você pode usar String.split (..) conforme mencionado nas outras respostas para a implementação.

Você deve escrever alguns testes de unidade para cadeias de caracteres de entrada e os resultados e comportamento desejados.

Bons candidatos a teste devem incluir:

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

Com a definição dos resultados do teste de acordo, você pode especificar o comportamento.

Por exemplo, se "-333"deve retornar [,333]ou se é um erro. Pode "333-333-33"ser separado [333,333-33] or [333-333,33]ou é um erro? E assim por diante.


4
Conselhos úteis, mas na verdade não são uma resposta para a pergunta. Se você apoia outras respostas com detalhes, é preferível comentar.
precisa

Use: split (regex String, limite int) e não dividido (String regex) para a visita de referência geeksforgeeks.org/split-string-java-examples
Ryan Augustine

16

Você pode tentar assim também

 String concatenated_String="hi^Hello";

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

16

Assumindo que

  • você realmente não precisa de expressões regulares para sua divisão
  • você já usa o apache commons lang em seu aplicativo

A maneira mais fácil é usar o StringUtils # split (java.lang.String, char) . Isso é mais conveniente do que o fornecido por Java imediatamente, se você não precisar de expressões regulares. Como o manual diz, funciona assim:

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

Eu recomendaria o uso do commong-lang, pois geralmente contém muitas coisas úteis. No entanto, se você não precisar dele para nada além de fazer uma divisão, implementar-se ou escapar do regex é uma opção melhor.


15

Use o método de divisão org.apache.commons.lang.StringUtils, que pode dividir cadeias com base no caractere ou na cadeia que você deseja dividir.

Assinatura do método:

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

No seu caso, você deseja dividir uma string quando houver um "-".

Você pode simplesmente fazer o seguinte:

String str = "004-034556";

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

Resultado:

004
034556

Suponha que, se -não existir na sua sequência, ela retornará a sequência especificada e você não receberá nenhuma exceção.


14

Resumindo: existem pelo menos cinco maneiras de dividir uma sequência em 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 (classe herdada):

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

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

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

Assim, você pode escolher a melhor opção para você, dependendo do que você precisa, por exemplo, tipo de retorno (matriz, lista ou iterável).

Aqui está uma grande visão geral desses métodos e os exemplos mais comuns (como dividir por ponto, barra, ponto de interrogação etc.)


13

A maneira mais rápida, que também consome menos recursos, pode 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 '-'
}

6
O recurso mais escasso é geralmente o tempo e a atenção do programador. Esse código consome mais esse recurso do que alternativas.
precisa

você tem um monte de built-in recursos que você pode usar, onde o desempenho é realmente considerado, esta solução é falta de tempo de execução desempenho
J Sanchez

1
Para fazer uma divisão simples em um único caractere com verificação de erro, isso não é mais complexo que a versão regex.
precisa saber é o seguinte

Bravo! Finalmente, uma resposta a esta pergunta que não usa regex! O uso de um regex para esta tarefa simples é um arrancador de cabeças. É bom ver que ainda existem programadores sãos nesta terra :-)
Gabriel Magana

Há apenas um "-", uma exceção é desejada e o resultado deve ir para string1 e string2. Faça string1 = s.substring(0, s.indexOf("-")); string2 = s.substring(s.indexOf("-") + 1);disso. Você receberá StringIndexOutOfBoundsExceptionautomaticamente se não houver "-".
Kaplan

13

String Split com vários 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]);
        }
     }
  }

Resultado:

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

Mas não espere a mesma saída em todas as versões do JDK. Eu vi um bug que existe em algumas versões do JDK em que a primeira cadeia nula foi ignorada. Esse bug não está presente na versão mais recente do JDK, mas existe em algumas versões entre as versões finais do JDK 1.7 e 1.8.


13

Para casos de uso simples, String.split()deve fazer o trabalho. Se você usa goiaba, também há uma classe Splitter que permite encadear diferentes operações de string e suporta o 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

Você pode dividir uma seqüência de caracteres por uma quebra de linha usando a seguinte instrução:

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

Você pode dividir uma string por um hífen / caractere usando a seguinte instrução:

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
se posso compartilhar conselhos, como sua resposta agrega mais valor do que a solução já aceita? stackoverflow.com/a/3481842/420096 nessas situações, você pode votar na solução existente, especialmente se esse for um caso trivial claro como esse.
Sombriks

8

Você pode 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];
    }
}

Senão, você pode usar o 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

Existem apenas dois métodos que você realmente precisa considerar.

Use String.split para um delimitador de um caractere ou você não se importa com o desempenho

Se o desempenho não for um problema ou se o delimitador for um único caractere que não seja um caractere especial de expressão regular (ou seja, não um .$|()[{^?*+\), você poderá usá-lo String.split.

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

O método split possui uma otimização para evitar o uso de uma expressão regular se o delimitador for um único caractere e não estiver na lista acima. Caso contrário, ele deve compilar uma expressão regular, e isso não é o ideal.

Use Pattern.split e pré-compile o padrão se estiver usando um delimitador complexo e se preocupa com o desempenho.

Se o desempenho for um problema e o seu delimitador não for um dos itens acima, você deverá pré-compilar um padrão de expressão regular que poderá reutilizar.

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

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

Esta última opção ainda cria um novo Matcherobjeto. Você também pode armazenar em cache esse objeto e redefini-lo para cada entrada para obter o máximo desempenho, mas isso é um pouco mais complicado e não é seguro para threads.


7

Uma maneira de fazer isso é percorrer a String em um loop for-each e usar o caractere de divisão necessário.

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

Resultado:

The split parts of the String are:
004
034556

7

Por favor, não use a classe StringTokenizer , pois é uma classe herdada que é mantida por motivos de compatibilidade e seu uso é desencorajado no novo código. E podemos fazer uso do método split, conforme sugerido por outros também.

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

E como esperado, ele será impresso:

[004, 034556]

Nesta resposta, também quero apontar uma mudança que ocorreu no splitmétodo em Java 8 . O método String # split () faz uso Pattern.splite agora removerá cadeias vazias no início da matriz de resultados. Observe esta mudança na documentação para Java 8:

Quando houver uma correspondência de largura positiva no início da sequência de entrada, uma subseqüência inicial vazia será incluída no início da matriz resultante. No entanto, uma correspondência de largura zero no início nunca produz essa substring inicial vazia.

Significa para o seguinte exemplo:

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

teremos três strings: [0, 0, 4]e não quatro, como era o caso do Java 7 e anterior. Verifique também essa pergunta semelhante .


7

Aqui estão duas maneiras pelas quais dois conseguem isso.

MANEIRA 1: Como você precisa dividir dois números por um caractere especial, pode usar regex

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

MANEIRA 2: Usando o método de divisão de cadeia

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

Você pode simplesmente usar o StringTokenizer para dividir uma sequência em duas ou mais partes, se houver algum tipo de delimitador:

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

4

Confira o split()método na Stringclasse em 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++;
}

Aqui estão muitos exemplos de string dividida, mas eu pouco código otimizado.


Substitua -por |e veja o que acontece :) #
R R Sun


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

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

3

Eu só queria escrever um algoritmo em vez de usar as funções internas do 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

Você pode usar o 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 \"-\".");
        }
    }
}

1

Para dividir uma sequência, use String.split (regex). Revise os seguintes exemplos:

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

Resultado

004
034556

Nota:

Essa divisão (regex) recebe uma regex como argumento. Lembre-se de escapar dos caracteres especiais regex, como ponto / ponto.


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 mencionado por todos, split () é a melhor opção que pode ser usada no seu caso. Um método alternativo pode estar usando substring ().


0

Para dividir uma sequência, use String.split(regex):

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

Resultado:

004
034556
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.