Dividir uma string por outra string em C #

681

Eu tenho usado o Split()método para dividir strings, mas isso só parece funcionar se você estiver dividindo uma string por um caractere. Existe uma maneira de dividir um string, com outra string sendo dividida por parâmetro?

Eu tentei converter o divisor em uma matriz de caracteres, sem sorte.

Em outras palavras, eu gostaria de dividir o string:

THExxQUICKxxBROWNxxFOX

por xxe retorne uma matriz com valores:

A RÁPIDA RAPOSA MARROM

Brandon
fonte
2
Para preocupações futuras: Um dos comentários abaixo me interessou, por isso decidi abrir uma discussão sobre engenharia de software sobre a maneira não intuitiva (mas correta) de fazê-lo na resposta aceita.
scharette

Respostas:

1238

Para dividir por uma sequência, você precisará usar a sobrecarga da matriz .

string data = "THExxQUICKxxBROWNxxFOX";

return data.Split(new string[] { "xx" }, StringSplitOptions.None);
Adam Robinson
fonte
4
Na verdade, acabei alterando minha resposta a isso por 2 razões: # 1: Para lidar com as divisões que eu quero fazer, eu precisaria usar o Regex.Escape, porque minha string de divisão geralmente conterá asteriscos, etc. # 2: Enquanto este programa Estou escrevendo não precisa de otimização real, parece haver sobrecarga adicional envolvida com o uso do método Regex Split.
Brandon
7
@ Peter: Nesse post, Jon está sugerindo porque o pôster não possui um delimitador fixo; ele está procurando dividir cadeias separadas por "mais de um espaço" (significando 2 ou mais). Para cadeias delimitadas por um padrão e não por um valor , o RegEx é uma ótima (bem, a única ) opção. Para delimitadores de valor fixo, ele apresenta sobrecarga desnecessária. Tente executar um teste; À medida que o número de operações aumenta, o RegEx acaba levando algo em torno de ~ 10x, contanto que o correspondente string.Split.
Adam Robinson
9
Eu venho de Python para C #. Python suporta string dividida por outra string. E frequentemente preciso voltar a esta pergunta para obter uma resposta simples string[] Split(string pattern), qual é o uso mais natural em que pude pensar, mas ainda não existe. Eu escrevi C antes, então estou acostumado a matrizes de caracteres, mas ainda odeio char[]aparecer em um código C # porque, de repente, arrasta minha atenção do nível do fluxo para o nível de bytes. Alguém sabe por que os caras da biblioteca C # criaram o método Split assim? Se houver um bom motivo, provavelmente posso tentar apreciá-lo, apesar dos inconvenientes.
foresightyj
11
Esse snippet está muito alto na lista de coisas que eu teria vergonha de mostrar aos desenvolvedores não C #.
Traubenfuchs
98
Por que diabos não podemos simplesmente fazer data.Split("xx")?
Mcont
122

Há uma sobrecarga de Split que recebe seqüências de caracteres.

"THExxQUICKxxBROWNxxFOX".Split(new [] { "xx" }, StringSplitOptions.None);

Você pode usar qualquer um desses StringSplitOptions

  • Nenhum - o valor de retorno inclui elementos da matriz que contêm uma sequência vazia
  • RemoveEmptyEntries - O valor de retorno não inclui elementos de matriz que contêm uma sequência vazia

Portanto, se a seqüência de caracteres for "THExxQUICKxxxxBROWNxxFOX", StringSplitOptions.Noneretornará uma entrada vazia na matriz para a parte "xxxx", enquanto StringSplitOptions.RemoveEmptyEntriesnão será.

Greg
fonte
73
Regex.Split(string, "xx")

é o jeito que eu faço normalmente.


Claro que você precisará de:

using System.Text.RegularExpressions;

ou:

System.Text.RegularExpressions.Regex.Split(string, "xx")

mas, novamente, eu preciso dessa biblioteca o tempo todo.

Pedro
fonte
13
@Brandon: Embora eu esteja sempre alertando contra a otimização prematura, você deve estar ciente de que a RegEx.Splité um pouco mais cara do que uma simples String.Splitpor causa da sobrecarga da expressão regular.
Adam Robinson
9
Se você deseja dividir por uma sequência arbitrária, use Regex.Escapeprimeiro a sequência, isso escapará a qualquer metacaractere de expressão regular.
Richard Richard
uma das principais vantagens que podem pagar por sobrecarga é capacidade de fornecer ajuste comparação de string
Timur Sadykov
47

Há uma sobrecarga de String.Split para isso:

"THExxQUICKxxBROWNxxFOX".Split(new [] {"xx"}, StringSplitOptions.None);
bruno conde
fonte
1
A única resposta que remove a declaração de tipo de matriz desnecessária.
wonea
25

Eu geralmente gosto de usar minha própria extensão para isso:

string data = "THExxQUICKxxBROWNxxFOX";
var dataspt = data.Split("xx");
//>THE  QUICK  BROWN  FOX 


//the extension class must be declared as static
public static class StringExtension
{   
    public static string[] Split(this string str, string splitter)
    {
        return str.Split(new[] { splitter }, StringSplitOptions.None);
    }
}

No entanto, isso levará a uma exceção, se a Microsoft decidir incluir essa sobrecarga de método em versões posteriores. Também é a provável razão pela qual a Microsoft não incluiu esse método nesse meio tempo: pelo menos uma empresa em que trabalhei, usou essa extensão em todos os seus projetos de C #.

Também pode ser possível definir condicionalmente o método em tempo de execução, se ele não existir.

Lorenz Lo Sauer
fonte
4
Como alternativa, use params string[] splittercomo o segundo parâmetro e altere new[] {splitter}para splitterpara suportar vários delimitadores.
Matthew Strawbridge
10

As respostas anteriores estão todas corretas. Vou um passo além e faço o C # funcionar para mim, definindo um método de extensão na String:

public static class Extensions
{
    public static string[] Split(this string toSplit, string splitOn) {
        return toSplit.Split(new string[] { splitOn }, StringSplitOptions.None);
    }
}

Dessa forma, eu posso chamá-lo em qualquer string da maneira simples que esperei ingenuamente na primeira vez que tentei fazer isso:

"a big long string with stuff to split on".Split("g str");
argyle
fonte
7
string data = "THExxQUICKxxBROWNxxFOX";

return data.Replace("xx","|").Split('|');

Basta escolher o caractere de substituição com cuidado (escolha um que provavelmente não esteja presente na string)!

SNag
fonte
2
@MasoudHosseini: Por favor, leia a resposta completa; já existe um aviso.
SNag
3
@kobe: Porque é um truque terrível.
Overv
3
Funciona bem, mas é perigoso para métodos genéricos
Kaizonaro
5
Postar explicações como "É um truque terrível" ou "uma resposta ruim" não é útil. É simplesmente uma opinião sem explicação. Em vez disso, afirme algo como "É desnecessário verificar a seqüência de caracteres em busca de substituições e depois procurar caracteres divididos, pois isso leva a um desempenho ruim". seria uma maneira melhor de se explicar. Muitos programadores agem dessa maneira. :(
Matt Ruwe
1
E se a string |já contiver o caractere, por esse motivo, acho que é perigoso usá-lo.
28418 amd
-1

Isso também é fácil:

string data = "THExxQUICKxxBROWNxxFOX";
string[] arr = data.Split("xx".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
user890255
fonte
1
Mas isso também iria dividir "THExQUICK"em que não quer que ele seja dividido
Rafalon
Obrigado Rafalon: sim, Greg é a melhor resposta: data.Split (nova string [] {"xx"}, StringSplitOptions.RemoveEmptyEntries)
user890255
-4

A maneira mais fácil é usar String.Replace:

string myString = "THExxQUICKxxBROWNxxFOX";
mystring = mystring.Replace("xx", ", ");

Ou, mais simplesmente:

string myString = "THExxQUICKxxBROWNxxFOX".Replace("xx", ", ");
user3458227
fonte
3
Como é, isso não retornará uma matriz (como a pergunta pede), apenas uma string com vírgulas onde xxestavam.
Arj
E não apenas isso, se a string contivesse vírgulas adicionais, você não seria capaz de dividir as palavras corretamente.
User3658298