Detectando "\" (barra invertida) usando Regex

Tengo un C# Regex como

[\"\'\\/]+

que quiero usar para evaluar y devolver un error si se encuentran ciertos caracteres especiales en una cadena.

Mi cadena de prueba es:

\test

Tengo una llamada a este método para validar la cadena:

public static bool validateComments(string input, out string errorString)
{
    errorString = null;
    bool result;

    result = !Regex.IsMatch(input, "[\"\'\\/]+");  // result is true if no match
                                                   // return an error if match

    if (result == false)
        errorString = "Comments cannot contain quotes (double or single) or slashes.";

    return result;
}

Sin embargo, no puedo hacer coincidir la barra invertida. Probé varias herramientas como regexpal y una extensión VS2012 que parecen coincidir con esta expresión regular muy bien, pero el código C# en sí no lo hará. Me doy cuenta de que C # está escapando de la cadena cuando proviene de una llamada Javascript Ajax, entonces, ¿hay otra forma de hacer coincidir esta cadena?

Coincide con /test o 'test o "test, pero no \test

preguntado el 11 de septiembre de 13 a las 14:09

Esto es más eficiente y más legible que regex: input.Contains('\\') -

@Tim, en realidad estoy buscando varios personajes. -

Fue solo un ejemplo. Aquí hay otro para las citas: input.Contains('"') || input.Contains('\'');. También podría poner los caracteres en una matriz y usar linq para evaluar la entrada: bool anyQuotes=quotesChars.Any(c=>input.Contains(c)). -

Entonces, ¿agregar los 4 controles juntos es mejor que un Regex? -

¿En términos de legibilidad (para la mayoría de las personas) y eficiencia? Sí. Los métodos de cadena son casi siempre más rápidos que las expresiones regulares, si es que puede usarlos. -

4 Respuestas

El \ es utilizado incluso por Regex(es). Tratar "[\"\'\\\\/]+" (así que doble escape del \)

Tenga en cuenta que podría tener @"[""'\\/]+" y tal vez sería más legible :-) (usando el @ el único personaje del que tienes que escapar es el ", mediante el uso de un segundo "")

Realmente no necesitas el +, porque al final [...] significa "uno de", y es suficiente para ti.

No comas lo que no puedes masticar... En lugar de expresiones regulares, usa

// result is true if no match
result = input.IndexOfAny(new[] { '"', '\'', '\\', '/' }) == -1;  

No creo que nadie haya perdido nunca el trabajo porque prefirió IndexOf en lugar de una expresión regular :-)

Respondido el 11 de Septiembre de 13 a las 14:09

Eso se ve muy extraño, pero sí, funciona. Personajes de escape... imagínense. - filetio

@Philethius Hay toneladas de expresiones en expresiones regulares como \w (coincide con cualquier carácter de palabra), por lo que es normal que el \ debe ser escapado. Entonces tienes que luchar contra el escape de la cuerda, así que \\\\ (o mejor, usa siempre @"..." al escribir expresiones regulares) - xanatos

Sí, eso tiene sentido. Haré una nota mental sobre ser más explícito con Regexes en mi código. - filetio

Puedes resolver esto haciendo la cadena textualmente así @:

result = !Regex.IsMatch(input, @"[\""\'\\/]+");

Respondido el 11 de Septiembre de 13 a las 14:09

Definitivamente la mejor idea con Regex. Las barras invertidas de escape doble son realmente confusas, y las cadenas textuales realmente ayudan a eliminar la confusión. - donante

Se corrigieron las comillas (estas son las únicas cosas que necesitan escapar con cadenas textuales) - donante

@ Philethius En realidad, no necesita escapar de esos dos de todos modos. - Ibrahim Najar

@spender Gracias, tienes razón. Acabo de recordar que necesitas el doble de comillas en una cadena textual, buena captura :) - Ibrahim Najar

No parece que puedas dejar de escapar o duplicarte por completo... elige tu veneno. - filetio

Dado que las barras invertidas se usan como escapes dentro de las expresiones regulares, creo que es mejor usar cadenas textuales cuando trabajo con la biblioteca de expresiones regulares:

string input = @"\test";
bool result = !Regex.IsMatch(input, @"[""'\\]+");
//                                     ^^
// You need to double the double-quotes when working with verbatim strings;
// All other characters, including backslashes, remain unchanged.
if (!result) {
    Console.WriteLine("Comments cannot contain quotes (double or single) or slashes.");
}

El único problema con eso es que debe duplicar sus comillas dobles (que, irónicamente, es lo que debe hacer en su caso).

Demo en ideone.

Respondido el 11 de Septiembre de 13 a las 14:09

Para el caso trivial, puedo usar regexhero.net para su expresión de prueba usando el simple:

\\

validar

\test

El código generado por RegExHero:

string strRegex = @"\\";

RegexOptions myRegexOptions = RegexOptions.IgnoreCase;
Regex myRegex = new Regex(strRegex, myRegexOptions);
string strTargetString = @"\test";
foreach (Match myMatch in myRegex.Matches(strTargetString))
{
  if (myMatch.Success)
  {
    // Add your code here
  }
}

Respondido el 11 de Septiembre de 13 a las 14:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.