uma máquina de estado pode facilmente fazê-lo, mas é provavelmente um exagero se você precisar dele apenas para remover os espaços
Adrian
Adicionei uma referência sobre as diferentes maneiras de fazer isso em uma pergunta duplicada stackoverflow.com/a/37592018/582061 . Regex não era a maneira mais rápida de fazer isso.
perfil completo de Stian Standahl
Respostas:
468
string sentence ="This is a sentence with multiple spaces";RegexOptions options =RegexOptions.None;Regex regex =newRegex("[ ]{2,}", options);
sentence = regex.Replace(sentence," ");
Tenho copiar e colar isso e funciona. Realmente não gosto do REgex, mas desta vez ele salva minha vida.
Pokus 15/10/08
9
@ Craig um comentário seria suficiente, IMO. // Este bloco substitui vários espaços por um ... :) #
paulwhit
6
Realmente, o RegEx é um exagero para isso.
Joel Coehoorn
11
@ Joel: Não posso concordar. Na verdade, tenho certeza de que esse caminho é mais eficiente que o seu para seqüências grandes o suficiente e pode ser feito em uma única linha. Onde está o exagero?
21978 Konrad Rudolph
24
O código de @Oscar Joel não é um loop simples em todos os personagens! É um loop aninhado oculto que tem um pior caso quadrático. Essa expressão regular, por outro lado, é linear, apenas cria uma única string (= custos de alocação drasticamente reduzidos em comparação com o código de Joel) e, além disso, o mecanismo pode otimizar o inferno (para ser sincero, duvido que o regex .NET seja inteligente o suficiente para isso, mas, em teoria, essa expressão regular pode ser implementada tão barata que nem sequer é mais engraçada; ela precisa apenas de um DFA com três estados, uma transição cada e sem informações adicionais).
Konrad Rudolph
623
Eu gosto de usar:
myString =Regex.Replace(myString,@"\s+"," ");
Uma vez que ele captura execuções de qualquer tipo de espaço em branco (por exemplo, guias, novas linhas etc.) e as substitui por um único espaço.
Ligeira modificação: Regex.Replace (origem, @ "(\ s) \ s +", "$ 1"); Isso retornará o primeiro tipo de espaço em branco encontrado. Portanto, se você tiver 5 guias, ele retornará uma guia. Caso alguém prefira isso.
FB ten Kate
@radistao Seu link é para substituição de string Javascript, não para C #.
Shiva
1
@Shiva, / \ s \ s + / é uma declaração POSIX regex padrão e pode ser convertido / utilizado em qualquer idioma usando própria sintaxe
radistao
4
No espírito da solução da @ FBtenKate: Regex.Replace (source, @ "(\ s) \ 1+", "$ 1"); substituirá vários caracteres consecutivos idênticos por um único.
François Beaune
1
para remover os espaços em branco iniciais e finais, você deve usar a função Trim () com isso, como var myString = Regex.Replace (myString, @ "\ s +", "") .Trim ();
Esta é mais legível sobre regex, eu preferi-lo mais, porque eu não preciso de aprender alguma outra sintaxe
Michael Bahig
9
Eu gosto dele porque ele não precisa Regex
AleX_
3
Isso seria ineficiente para cadeias grandes.
DarcyThomas 28/09
3
Isso também remove os espaços iniciais e finais.
Matzi 5/02
1
Eu prefiro essa resposta também. Meu antigo mentor usado para dizer "quando você tem um problema que você acha que precisa de Regex para resolver, bem ... agora você tem dois problemas" <piscadela>
William Madonna Jr.
38
Acho que a resposta de Matt é a melhor, mas não acredito que esteja certa. Se você deseja substituir novas linhas, você deve usar:
RegexOptions.Multiline altera o significado de ^ e $ para que correspondam ao início e ao final de cada linha ($ = \ n), em vez de toda a sequência de várias linhas. Como \ s é equivalente a [\ f \ n \ r \ t \ v], as novas linhas devem ser substituídas mesmo se a opção Multilinha estiver desativada.
SushiGuy
1
A resposta de Matt já cobriu isso. I 'Believe' 30 pessoas apenas os olhos vendados up-votado esta resposta :)
Isso será muito menos eficiente que o regex "{2,}" se a sequência contiver seqüências de 3 ou mais espaços.
Jan Goyvaerts
2
@ JanGoyvaerts: Mesmo com 10 espaços, o regex era mais lento quando eu fiz um teste rápido e sujo. Dito isto, são necessárias apenas uma subcadeia gigante cheia de espaços para eliminar completamente o desempenho do loop while. Para ser justo, usei o RegexOptions.Compiled, em vez do Regex.Replace mais lento.
22713 Brian
5
RegexOptions.Compiled adiciona muita sobrecarga compilando o regex em IL. Não o use, a menos que seu aplicativo use a regex com frequência suficiente ou em cadeias grandes o suficiente para que a maior velocidade de correspondência compense a menor velocidade de compilação.
Jan Goyvaerts
Este é um exemplo de código extremamente ineficiente. RI MUITO.
pcbabu 19/02
1
@pcbabu Não é tão ruim quanto parece para muitos casos. O Replace()método manipula todas as ocorrências de dois espaços em uma determinada sequência, portanto, não estamos fazendo loop (e alocando uma sequência inteira) para todas as instâncias de espaços emparelhados na sequência. Uma nova alocação tratará de todos eles. Só executamos novamente o loop quando havia 3 ou mais espaços juntos, o que provavelmente será uma ocorrência mais rara para muitas fontes de entrada. Se você puder mostrar que isso se torna um problema para seus dados, escreva a máquina de estado para inserir caracteres por caractere em um novo construtor de strings.
Joel Coehoorn
21
Regex pode ser bastante lento, mesmo com tarefas simples. Isso cria um método de extensão que pode ser usado em qualquer um string.
publicstaticclassStringExtension{publicstaticStringReduceWhitespace(thisStringvalue){var newString =newStringBuilder();bool previousIsWhitespace =false;for(int i =0; i <value.Length; i++){if(Char.IsWhiteSpace(value[i])){if(previousIsWhitespace){continue;}
previousIsWhitespace =true;}else{
previousIsWhitespace =false;}
newString.Append(value[i]);}return newString.ToString();}}
Seria usado como tal:
string testValue ="This contains too much whitespace."
testValue = testValue.ReduceWhitespace();// testValue = "This contains too much whitespace."
Para quem não gosta Regex, aqui está um método que usa StringBuilder:
publicstaticstringFilterWhiteSpaces(string input){if(input ==null)returnstring.Empty;StringBuilder stringBuilder =newStringBuilder(input.Length);for(int i =0; i < input.Length; i++){char c = input[i];if(i ==0|| c !=' '||(c ==' '&& input[i -1]!=' '))
stringBuilder.Append(c);}return stringBuilder.ToString();}
Nos meus testes, esse método era 16 vezes mais rápido, em média, com um conjunto muito grande de cadeias de tamanho pequeno a médio, em comparação com um Regex compilado estático. Comparado a um Regex não compilado ou não estático, isso deve ser ainda mais rápido.
Lembre-se de que ele não remove espaços à esquerda ou à direita, apenas várias ocorrências desse tipo.
Você precisa garantir que sua string não tenha "()" ou ") (" nela. Ou "wel()come to london)("se torna "wel come to london". Você pode tentar usar muitos colchetes. Portanto, use em ((((()))))vez de ()e em )))))(((((vez de )(. Ainda funcionará. Ainda assim, se a string contém ((((()))))ou )))))(((((, isso falhará #
nmit026
7
Esta é uma versão mais curta, que só deve ser usada se você estiver fazendo isso uma vez, pois ela cria uma nova instância da Regexclasse toda vez que é chamada.
temp =newRegex(" {2,}").Replace(temp," ");
Se você não conhece muito expressões regulares, aqui está uma breve explicação:
O {2,}torna a pesquisa regex para o personagem que o precede, e encontra substrings entre 2 e ilimitadas vezes.
o.Replace(temp, " ") substitui todas as correspondências na string temp por um espaço.
Se você deseja usar isso várias vezes, aqui está uma opção melhor, pois ela cria a IL do regex em tempo de compilação:
Uma palavra de cautela: O uso da divisão, embora muito simples de entender, pode ter um impacto surpreendentemente negativo no desempenho. Como muitas seqüências de caracteres podem ser criadas, você precisará observar o uso da memória caso lide com grandes seqüências com esse método.
Pac0
5
Consolando outras respostas, por Joel, e, esperançosamente, melhorando um pouco à medida que vou:
por que criar um método de extensão? por que não usar string.Join ()?
Eric Schoonover
3
// Mysample stringstring str ="hi you are a demo";//Split the words based on white sapcevar demo= str .Split(' ').Where(s =>!string.IsNullOrWhiteSpace(s));//Join the values back and add a single space in between
str =string.Join(" ", demo);//output: string str ="hi you are a demo";
Eu sei que isso é bem antigo, mas me deparei com isso enquanto tentava realizar quase a mesma coisa. Encontrei esta solução no RegEx Buddy. Esse padrão substitui todos os espaços duplos por espaços simples e também apara os espaços iniciais e finais.
pattern:(?m:^+|+$|(){2,})
replacement: $1
É um pouco difícil de ler, já que estamos lidando com espaço vazio, então aqui está novamente com os "espaços" substituídos por um "_".
pattern:(?m:^_+|_+$|(_){2,})<-- don't use this, just for illustration.
A construção "(? M:" ativa a opção "multi-line". Geralmente, gosto de incluir todas as opções possíveis no próprio padrão, para que fique mais independente.
Muitas respostas estão fornecendo a saída certa, mas para aqueles que procuram as melhores performances, eu melhorei a resposta de Nolanar (que foi a melhor resposta para o desempenho) em cerca de 10%.
publicstaticstringMergeSpaces(thisstring str){if(str ==null){returnnull;}else{StringBuilder stringBuilder =newStringBuilder(str.Length);int i =0;foreach(char c in str){if(c !=' '|| i ==0|| str[i -1]!=' ')
stringBuilder.Append(c);
i++;}return stringBuilder.ToString();}}
while word.contains(" ")//double space
word = word.Replace(" "," ");//replace double space by single space.
word = word.trim();//to remove single whitespces from start & end.
using System;
using System.Linq;
using System.Text;publicstaticclassStringExtension{publicstaticstringStripSpaces(thisstring s){return s.Aggregate(newStringBuilder(),(acc, c)=>{if(c !=' '|| acc.Length>0&& acc[acc.Length-1]!=' ')
acc.Append(c);return acc;}).ToString();}publicstaticvoidMain(){Console.WriteLine("\""+StringExtension.StripSpaces("1 Hello World 2 ")+"\"");}}
Respostas:
fonte
Eu gosto de usar:
Uma vez que ele captura execuções de qualquer tipo de espaço em branco (por exemplo, guias, novas linhas etc.) e as substitui por um único espaço.
fonte
fonte
Acho que a resposta de Matt é a melhor, mas não acredito que esteja certa. Se você deseja substituir novas linhas, você deve usar:
fonte
Outra abordagem que usa o LINQ:
fonte
É muito mais simples do que tudo isso:
fonte
Replace()
método manipula todas as ocorrências de dois espaços em uma determinada sequência, portanto, não estamos fazendo loop (e alocando uma sequência inteira) para todas as instâncias de espaços emparelhados na sequência. Uma nova alocação tratará de todos eles. Só executamos novamente o loop quando havia 3 ou mais espaços juntos, o que provavelmente será uma ocorrência mais rara para muitas fontes de entrada. Se você puder mostrar que isso se torna um problema para seus dados, escreva a máquina de estado para inserir caracteres por caractere em um novo construtor de strings.Regex pode ser bastante lento, mesmo com tarefas simples. Isso cria um método de extensão que pode ser usado em qualquer um
string
.Seria usado como tal:
fonte
fonte
Para quem não gosta
Regex
, aqui está um método que usaStringBuilder
:Nos meus testes, esse método era 16 vezes mais rápido, em média, com um conjunto muito grande de cadeias de tamanho pequeno a médio, em comparação com um Regex compilado estático. Comparado a um Regex não compilado ou não estático, isso deve ser ainda mais rápido.
Lembre-se de que ele não remove espaços à esquerda ou à direita, apenas várias ocorrências desse tipo.
fonte
Você pode simplesmente fazer isso em uma solução de linha!
Você pode escolher outros colchetes (ou até outros caracteres), se quiser.
fonte
"wel()come to london)("
se torna"wel come to london"
. Você pode tentar usar muitos colchetes. Portanto, use em((((()))))
vez de()
e em)))))(((((
vez de)(
. Ainda funcionará. Ainda assim, se a string contém((((()))))
ou)))))(((((
, isso falhará #Esta é uma versão mais curta, que só deve ser usada se você estiver fazendo isso uma vez, pois ela cria uma nova instância da
Regex
classe toda vez que é chamada.Se você não conhece muito expressões regulares, aqui está uma breve explicação:
O
{2,}
torna a pesquisa regex para o personagem que o precede, e encontra substrings entre 2 e ilimitadas vezes.o
.Replace(temp, " ")
substitui todas as correspondências na string temp por um espaço.Se você deseja usar isso várias vezes, aqui está uma opção melhor, pois ela cria a IL do regex em tempo de compilação:
fonte
no Regex, no Linq ... remove os espaços iniciais e finais, além de reduzir qualquer segmento de espaço múltiplo incorporado em um espaço
resultado: "0 1 2 3 4 5"
fonte
Consolando outras respostas, por Joel, e, esperançosamente, melhorando um pouco à medida que vou:
Você pode fazer isso com
Regex.Replace()
:Ou com
String.Split()
:fonte
Acabei de escrever um novo
Join
que eu gosto, então pensei em responder novamente:Uma das coisas legais sobre isso é que ele trabalha com coleções que não são strings, chamando ToString () nos elementos. O uso ainda é o mesmo:
fonte
fonte
Eu sei que isso é bem antigo, mas me deparei com isso enquanto tentava realizar quase a mesma coisa. Encontrei esta solução no RegEx Buddy. Esse padrão substitui todos os espaços duplos por espaços simples e também apara os espaços iniciais e finais.
É um pouco difícil de ler, já que estamos lidando com espaço vazio, então aqui está novamente com os "espaços" substituídos por um "_".
A construção "(? M:" ativa a opção "multi-line". Geralmente, gosto de incluir todas as opções possíveis no próprio padrão, para que fique mais independente.
fonte
Muitas respostas estão fornecendo a saída certa, mas para aqueles que procuram as melhores performances, eu melhorei a resposta de Nolanar (que foi a melhor resposta para o desempenho) em cerca de 10%.
fonte
Posso remover espaços em branco com este
fonte
Use o padrão regex
fonte
tente este método
use-o assim:
fonte
Aqui está uma pequena modificação na resposta original do Nolonar .
Verificando se o caractere não é apenas um espaço, mas qualquer espaço em branco, use o seguinte:
Ele substituirá qualquer caractere de espaço em branco múltiplo por um único espaço.
fonte
Skool antigo:
fonte
Sem usar expressões regulares:
OK para usar em cadeias curtas, mas terá um desempenho ruim em cadeias longas com muitos espaços.
fonte
Mistura de StringBuilder e Enumerable.Aggregate () como método de extensão para seqüências de caracteres:
Entrada:
Resultado:
fonte