2010-07-21 238 views
55

Soy completamente incapaz de expresiones regulares, por lo que necesito ayuda con un problema que creo que se resolvería mejor mediante el uso de expresiones regulares.Regex para eliminar todos los caracteres especiales de la cadena?

que tienen lista de cadenas en C#:

List<string> lstNames = new List<string>(); 
lstNames.add("TRA-94:23"); 
lstNames.add("TRA-42:101"); 
lstNames.add("TRA-109:AD"); 

foreach (string n in lstNames) { 
    // logic goes here that somehow uses regex to remove all special characters 
    string regExp = "NO_IDEA"; 
    string tmp = Regex.Replace(n, regExp, ""); 
} 

tengo que ser capaz de bucle sobre la lista y volver cada artículo sin ningún carácter especial. Por ejemplo, el ítem uno sería "TRA9423", el ítem dos sería "TRA42101" y el ítem tres sería TRA109AD.

¿Hay alguna expresión regular que pueda lograr esto por mí?

Además, la lista contiene más de 4000 elementos, por lo que necesito que la búsqueda y el reemplazo sean eficientes y rápidos si es posible.

EDIT: Debería haber especificado que cualquier carácter al lado de a-z, A-Z y 0-9 es especial en mi circunstancia.

+2

4000 es una cantidad muy pequeña de artículos. ¿Por qué es tan importante que la respuesta sea eficiente y rápida en lugar de, por ejemplo, legible y mantenible? ¿Has medido un problema de rendimiento aquí? –

+0

@Mark: esto es solo mi ignorancia, supongo. 4000 me parece que es mucho, pero aparentemente estoy equivocado. No hice ningún punto de referencia, pero la expresión regular parece ser muy rápida de todos modos, así que no creo que deba perder el tiempo acelerando nada. En realidad, simplifiqué un poco mi ejemplo, porque no quería complicar innecesariamente mi pregunta. De hecho, tengo una lista de objetos de clase complejos, y estoy usando .FindAll con una función de delegado para encontrar todas las coincidencias. La expresión regular entra en juego en una propiedad de mi clase que usa la expresión regular para manipular una cierta cadena para la función de delegado. – Jagd

+0

¡Gracias a todos por su ayuda! Ojalá todas las preguntas fueran así de genios como ustedes. : D – Jagd

Respuesta

91

Realmente depende de su definición de caracteres especiales. Me parece que una lista blanca en lugar de una lista negra es el mejor enfoque en la mayoría de situaciones:

tmp = Regex.Replace(n, "[^0-9a-zA-Z]+", ""); 

Usted debe tener cuidado con su enfoque actual, porque los dos elementos siguientes se convertirán en la misma cadena y por lo tanto serán indistinguibles:

"TRA-12:123" 
"TRA-121:23" 
+0

El cuantificador '+' es redundante. Si el personaje coincide, también coincidirá en una secuencia consecutiva de estos. –

+4

@Daniel, espero que el '+' haga la operación considerablemente más rápida, por supuesto que no importará a menos que se procese algo enorme. –

+0

No importa que ambos elementos terminen siendo los mismos, porque estoy haciendo una coincidencia difusa y espero tener varios elementos devueltos. Lista lstPax = lstReports.FindAll (delegar (PdfAndXml o) {return (o.Packed.Contains (findTxt));}); Packed es la propiedad en la que estoy usando la expresión regular para manipular un determinado atributo de cadena de la clase PdfAndXml. – Jagd

16

Esto debe hacerlo:

[^a-zA-Z0-9] 

Básicamente coincidir todos los caracteres no alfanuméricos.

15

[^a-zA-Z0-9] es una clase de caracteres coincide con todos los caracteres no alfanuméricos.

Alternativamente, [^\w\d] hace lo mismo.

Uso:

string regExp = "[^\w\d]"; 
string tmp = Regex.Replace(n, regExp, ""); 
+2

Probé ambas versiones en http://regexpal.com/ y encontré que "[^ \ w \ d]" no coincidiría con caracteres de subrayado mientras que [^ a-zA-Z0-9] lo haría. – Karle

3

En función de la definición de "carácter especial", creo que "[^ a-zA-Z0-9]" probablemente haría el truco. Eso encontraría cualquier cosa que no sea una letra pequeña, una letra mayúscula o un dígito.

+0

Oh, veo un patrón en desarrollo en las respuestas. – Jay

+4

¿El patrón es regular? – MikeD

2
tmp = Regex.Replace(n, @"\W+", ""); 

\w partidos letras, dígitos y guiones bajos, \W es la versión negada.

+0

Como define _ como especial, debería ir con una de las otras respuestas :) –

7

que puede utilizar:

string regExp = "\\W"; 

Esto es equivalente a Daniel "[^a-zA-Z0-9]"

\ W coincide con cualquier carácter de otro tipo. Equivalente a las categorías Unicode [^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}].

+3

también coincide con _ por lo que no es del todo perfecto aquí. –

+0

Ummm, tienes razón, no lo habría pensado por la descripción. Bien descrito. –

2

Para mis propósitos, quería todos los caracteres en inglés ASCII, así que funcionó.

html = Regex.Replace(html, "[^\x00-\x80]+", "") 
0

Si no desea utilizar expresiones regulares a continuación, otra opción es utilizar

char.IsLetterOrDigit 

Usted puede usar esto para recorrer cada carbón de la cadena y sólo volver si es cierto.

Cuestiones relacionadas