una máquina de estados puede hacerlo fácilmente, pero probablemente sea excesivo si solo lo necesita para eliminar espacios
Adrian
He agregado un punto de referencia sobre las diferentes formas de hacer esto en una pregunta duplicada stackoverflow.com/a/37592018/582061 . Regex no era la forma más rápida de hacer esto.
Stian Standahl
Respuestas:
469
string sentence ="This is a sentence with multiple spaces";RegexOptions options =RegexOptions.None;Regex regex =newRegex("[ ]{2,}", options);
sentence = regex.Replace(sentence," ");
Tengo copiar y pegar eso y funciona. Realmente no me gusta REgex pero esta vez me salva la vida.
Pokus
99
@Craig un comentario sería suficiente, en mi opinión. // Este bloque reemplaza múltiples espacios con uno ... :)
paulwhit
66
Realmente, RegEx es demasiado para esto.
Joel Coehoorn
11
@ Joel: No puedo estar de acuerdo. De hecho, estoy seguro de que esta forma es más eficiente que la suya para cadenas lo suficientemente grandes y se puede hacer en una sola línea. ¿Dónde está la exageración?
Konrad Rudolph el
24
¡El código de @Oscar Joel no es un simple bucle a través de todos los personajes! Es un bucle anidado oculto que tiene un peor caso cuadrático. Esta expresión regular, por el contrario, es lineal, solo acumula una sola cadena (= costos de asignación drásticamente reducidos en comparación con el código de Joel) y, además, el motor puede optimizar al máximo (para ser sincero, dudo que la expresión regular .NET sea lo suficientemente inteligente como para esto, pero en teoría esta expresión regular se puede implementar de manera tan económica que ya ni siquiera es graciosa; solo necesita un DFA con tres estados, una transición cada uno y sin información adicional).
Konrad Rudolph el
624
Me gusta usar:
myString =Regex.Replace(myString,@"\s+"," ");
Ya que capturará ejecuciones de cualquier tipo de espacio en blanco (por ejemplo, pestañas, líneas nuevas, etc.) y las reemplazará con un solo espacio.
Ligera modificación: Regex.Replace (fuente, @ "(\ s) \ s +", "$ 1"); Esto devolverá el primer tipo de espacio en blanco encontrado. Entonces, si tiene 5 pestañas, devolverá una pestaña. En caso de que alguien prefiera esto.
FB ten Kate
@radistao Su enlace es para reemplazar la cadena Javascript, no para C #.
Shiva
1
@Shiva, / \ s \ s + / es una declaración de expresión regular POSIX estándar y se puede convertir / usar en cualquier idioma usando su propia sintaxis
radistao
44
En el espíritu de la solución de @ FBtenKate: Regex.Replace (fuente, @ "(\ s) \ 1+", "$ 1"); reemplazará varios caracteres consecutivos idénticos por uno solo.
François Beaune
1
para eliminar espacios en blanco iniciales y finales, debe usar la función Trim () con esto, como var myString = Regex.Replace (myString, @ "\ s +", "") .Trim ();
Esto es más legible que regex, prefiero más porque no necesito aprender otra sintaxis
Michael Bahig
99
Me gusta porque no necesita Regex
AleX_
3
Esto sería ineficiente para cadenas grandes.
DarcyThomas
3
Esto también elimina los espacios iniciales y finales.
Matzi
1
Prefiero esta respuesta también. Mi antiguo mentor solía decir "cada vez que tienes un problema crees que necesitas que Regex lo resuelva, bueno ... ahora tienes DOS problemas" <wink>
William Madonna Jr.
38
Creo que la respuesta de Matt es la mejor, pero no creo que sea correcta. Si desea reemplazar las nuevas líneas, debe usar:
RegexOptions.Multiline cambia el significado de ^ y $ para que coincidan con el principio y el final de cada línea ($ = \ n), en lugar de la cadena completa de varias líneas. Como \ s es equivalente a [\ f \ n \ r \ t \ v], las nuevas líneas deben reemplazarse incluso si la opción Multilínea está desactivada.
SushiGuy
1
La respuesta de Matt ya ha cubierto esto. 'Creo' que 30 personas con los ojos vendados votaron por esta respuesta :)
Esto será mucho menos eficiente que la expresión regular "{2,}" si la cadena contiene secuencias de 3 o más espacios.
Jan Goyvaerts
2
@ JanGoyvaerts: Incluso con 10 espacios, la expresión regular fue más lenta cuando hice una prueba rápida y sucia. Dicho esto, solo se necesita una subcadena gigante llena de espacios para eliminar por completo el rendimiento del ciclo while. Para ser justos, usé RegexOptions.Compiled, en lugar del Regex.Replace más lento.
Brian
55
RegexOptions.Compiled agrega una gran cantidad de gastos generales al compilar la expresión regular en IL. No lo use a menos que su aplicación use la expresión regular con suficiente frecuencia o en cadenas lo suficientemente grandes como para que la mayor velocidad de coincidencia compense la menor velocidad de compilación.
Jan Goyvaerts
Este es un ejemplo de código extremadamente ineficiente. Jajaja
pcbabu
1
@pcbabu No es tan malo como parece en muchos casos. El Replace()método manejará todas las ocurrencias de dos espacios en una cadena dada, por lo que no estamos haciendo un bucle (y reasignando una cadena completa) para cada instancia de espacios emparejados en la cadena. Una nueva asignación se encargará de todos ellos. Solo volvemos a ejecutar el ciclo cuando había 3 o más espacios juntos, lo que probablemente sea una ocurrencia más rara para muchas fuentes de entrada. Si puede mostrar que se convierte en un problema para sus datos, vaya a escribir la máquina de estado para insertar carácter por carácter en un nuevo generador de cadenas.
Joel Coehoorn
21
Regex puede ser bastante lento incluso con tareas simples. Esto crea un método de extensión que puede usarse fuera de cualquier 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();}}
Sería utilizado como tal:
string testValue ="This contains too much whitespace."
testValue = testValue.ReduceWhitespace();// testValue = "This contains too much whitespace."
Para aquellos a quienes no les gusta Regex, aquí hay un método que utiliza 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();}
En mis pruebas, este método fue 16 veces más rápido en promedio con un conjunto muy grande de cadenas de tamaño pequeño a mediano, en comparación con un Regex compilado estático. En comparación con un Regex no compilado o no estático, esto debería ser aún más rápido.
Tenga en cuenta que no elimina los espacios iniciales o finales, solo ocurre múltiples veces .
Debe asegurarse de que su cadena no tenga "()" o ") (" en ella. O se "wel()come to london)("convierte "wel come to london". Puede intentar usar muchos corchetes. Por lo tanto, use en ((((()))))lugar de ()y en )))))(((((lugar de )(. Todavía funcionará. Aún así, si la cadena contiene ((((()))))o )))))(((((, esto fallará.
nmit026
7
Esta es una versión más corta, que solo debe usarse si solo lo hace una vez, ya que crea una nueva instancia de la Regexclase cada vez que se llama.
temp =newRegex(" {2,}").Replace(temp," ");
Si no está demasiado familiarizado con las expresiones regulares, aquí hay una breve explicación:
Esto {2,}hace que la expresión regular busque el carácter que le precede, y encuentra subcadenas entre 2 e ilimitadas veces.
El .Replace(temp, " ")reemplaza todas las coincidencias en la cadena temporal con un espacio.
Si desea usar esto varias veces, aquí hay una mejor opción, ya que crea la IL de expresión regular en tiempo de compilación:
Una advertencia: el uso de la división, si bien es muy sencillo de entender, puede tener un impacto sorprendentemente negativo en el rendimiento. Como se pueden crear muchas cadenas, tendrá que vigilar el uso de su memoria en caso de que maneje cadenas grandes con este método.
Pac0
5
Consolidando otras respuestas, según Joel, y con suerte mejorando ligeramente a medida que avanzo:
Una de las cosas interesantes de esto es que funciona con colecciones que no son cadenas, al llamar a ToString () en los elementos. El uso sigue siendo el mismo:
//...string s =" 1 2 4 5".Split(" ".ToCharArray(),StringSplitOptions.RemoveEmptyEntries).Join(" ");
¿Por qué crear un método de extensión? ¿Por qué no usar string.Join ()?
Eric Schoonover el
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";
Sé que esto es bastante viejo, pero me encontré con esto al intentar lograr casi lo mismo. Encontré esta solución en RegEx Buddy. Este patrón reemplazará todos los espacios dobles con espacios individuales y también recortará los espacios iniciales y finales.
pattern:(?m:^+|+$|(){2,})
replacement: $1
Es un poco difícil de leer ya que estamos tratando con un espacio vacío, así que aquí está nuevamente con los "espacios" reemplazados por un "_".
pattern:(?m:^_+|_+$|(_){2,})<-- don't use this, just for illustration.
La construcción "(? M:" habilita la opción "multilínea". En general, me gusta incluir todas las opciones que pueda dentro del patrón para que sea más autónomo.
Muchas respuestas están proporcionando el resultado correcto, pero para aquellos que buscan las mejores actuaciones, mejoré la respuesta de Nolanar (que fue la mejor respuesta para el rendimiento) en aproximadamente un 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 ")+"\"");}}
Respuestas:
fuente
Me gusta usar:
Ya que capturará ejecuciones de cualquier tipo de espacio en blanco (por ejemplo, pestañas, líneas nuevas, etc.) y las reemplazará con un solo espacio.
fuente
fuente
Creo que la respuesta de Matt es la mejor, pero no creo que sea correcta. Si desea reemplazar las nuevas líneas, debe usar:
fuente
Otro enfoque que usa LINQ:
fuente
Es mucho más simple que todo eso:
fuente
Replace()
método manejará todas las ocurrencias de dos espacios en una cadena dada, por lo que no estamos haciendo un bucle (y reasignando una cadena completa) para cada instancia de espacios emparejados en la cadena. Una nueva asignación se encargará de todos ellos. Solo volvemos a ejecutar el ciclo cuando había 3 o más espacios juntos, lo que probablemente sea una ocurrencia más rara para muchas fuentes de entrada. Si puede mostrar que se convierte en un problema para sus datos, vaya a escribir la máquina de estado para insertar carácter por carácter en un nuevo generador de cadenas.Regex puede ser bastante lento incluso con tareas simples. Esto crea un método de extensión que puede usarse fuera de cualquier
string
.Sería utilizado como tal:
fuente
fuente
Para aquellos a quienes no les gusta
Regex
, aquí hay un método que utilizaStringBuilder
:En mis pruebas, este método fue 16 veces más rápido en promedio con un conjunto muy grande de cadenas de tamaño pequeño a mediano, en comparación con un Regex compilado estático. En comparación con un Regex no compilado o no estático, esto debería ser aún más rápido.
Tenga en cuenta que no elimina los espacios iniciales o finales, solo ocurre múltiples veces .
fuente
¡Simplemente puede hacer esto en una solución de línea!
Puede elegir otros corchetes (o incluso otros caracteres) si lo desea.
fuente
"wel()come to london)("
convierte"wel come to london"
. Puede intentar usar muchos corchetes. Por lo tanto, use en((((()))))
lugar de()
y en)))))(((((
lugar de)(
. Todavía funcionará. Aún así, si la cadena contiene((((()))))
o)))))(((((
, esto fallará.Esta es una versión más corta, que solo debe usarse si solo lo hace una vez, ya que crea una nueva instancia de la
Regex
clase cada vez que se llama.Si no está demasiado familiarizado con las expresiones regulares, aquí hay una breve explicación:
Esto
{2,}
hace que la expresión regular busque el carácter que le precede, y encuentra subcadenas entre 2 e ilimitadas veces.El
.Replace(temp, " ")
reemplaza todas las coincidencias en la cadena temporal con un espacio.Si desea usar esto varias veces, aquí hay una mejor opción, ya que crea la IL de expresión regular en tiempo de compilación:
fuente
no Regex, no Linq ... elimina los espacios iniciales y finales, así como reduce cualquier segmento de espacio múltiple incrustado a un espacio
resultado: "0 1 2 3 4 5"
fuente
Consolidando otras respuestas, según Joel, y con suerte mejorando ligeramente a medida que avanzo:
Puedes hacer esto con
Regex.Replace()
:O con
String.Split()
:fuente
Acabo de escribir una nueva
Join
que me gusta, así que pensé en volver a responder, con ella:Una de las cosas interesantes de esto es que funciona con colecciones que no son cadenas, al llamar a ToString () en los elementos. El uso sigue siendo el mismo:
fuente
fuente
Sé que esto es bastante viejo, pero me encontré con esto al intentar lograr casi lo mismo. Encontré esta solución en RegEx Buddy. Este patrón reemplazará todos los espacios dobles con espacios individuales y también recortará los espacios iniciales y finales.
Es un poco difícil de leer ya que estamos tratando con un espacio vacío, así que aquí está nuevamente con los "espacios" reemplazados por un "_".
La construcción "(? M:" habilita la opción "multilínea". En general, me gusta incluir todas las opciones que pueda dentro del patrón para que sea más autónomo.
fuente
Muchas respuestas están proporcionando el resultado correcto, pero para aquellos que buscan las mejores actuaciones, mejoré la respuesta de Nolanar (que fue la mejor respuesta para el rendimiento) en aproximadamente un 10%.
fuente
Puedo eliminar espacios en blanco con esto
fuente
Usa el patrón regex
fuente
prueba este método
úsalo así:
fuente
Aquí hay una ligera modificación en la respuesta original de Nolonar .
Verificando si el personaje no es solo un espacio, sino cualquier espacio en blanco, use esto:
Reemplazará cualquier carácter de espacio en blanco múltiple con un solo espacio.
fuente
Vieja escuela:
fuente
Sin usar expresiones regulares:
Está bien usarlo en cadenas cortas, pero funcionará mal en cadenas largas con muchos espacios.
fuente
Mezcla de StringBuilder y Enumerable.Aggregate () como método de extensión para cadenas:
Entrada:
Salida:
fuente