solo - regex replace online
¿Cuándo es mejor usar Expresiones regulares sobre la división de cadenas básica/subcadena? (7)
Parece que la opción de utilizar el análisis sintáctico de cadenas frente a las expresiones regulares aparece de forma regular para mí cada vez que surge una situación en la que necesito parte de una cadena, información sobre dicha cadena, etc.
La razón por la que esto ocurre es que estamos evaluando la acción de un encabezado de soap, después de que se ha analizado en algo manejable mediante el objeto OperationContext para WCF y luego tomamos decisiones al respecto. En este momento, la solución simple parece ser una subcadena básica para mantener la implementación simple, pero una parte de mí se pregunta si RegEx sería mejor o más robusto. La otra parte de mí se pregunta si sería como usar una escopeta para matar una mosca en nuestro escenario particular.
Así que tengo que preguntar, ¿cuál es el umbral típico que las personas usan cuando intentan usar RegEx sobre el típico análisis sintáctico de cadenas? Tenga en cuenta que no soy muy fuerte en expresiones regulares, y debido a esto, trato de alejarme a menos que sea absolutamente vital evitar introducir más complicaciones de las que necesito.
Si no puede decirlo por mi elección de abreviaturas, esto está en .NET land (C #), pero creo que eso no tiene mucho que ver con la pregunta.
EDITAR : Parece ser que, según mi encanto típico de Raybell, he sido demasiado prolijo o engañoso en mi pregunta. Quiero pedir disculpas. Estaba dando algunos antecedentes para ayudar a dar pistas sobre lo que estaba haciendo, no engañar a la gente.
Básicamente, busco una guía sobre cuándo usar la subcadena, y sus variaciones, sobre las expresiones regulares y viceversa. Y aunque algunas de las respuestas pueden haber pasado por alto esto (y nuevamente, mi culpa), realmente las aprecié y voté como correspondía.
Espero que esto ayude algo.
Mi directriz principal es usar expresiones regulares para el código desechable, y para la validación de entrada del usuario. O cuando estoy tratando de encontrar un patrón específico dentro de un gran globo de texto. Para la mayoría de los demás propósitos, escribiré una gramática e implementaré un analizador simple.
Una directriz importante (que es realmente difícil de eludir, aunque veo que la gente lo intenta todo el tiempo) es usar siempre un analizador en los casos en que la gramática del idioma de destino sea recursiva.
Por ejemplo, considere un pequeño "lenguaje de expresión" para evaluar expresiones aritméticas entre paréntesis. Ejemplos de "programas" en este idioma se verían así:
1 + 2
5 * (10 - 6)
((1 + 1) / (2 + 2)) / 3
Una gramática es fácil de escribir, y se ve así:
DIGIT := ["0"-"9"]
NUMBER := (DIGIT)+
OPERATOR := ("+" | "-" | "*" | "/" )
EXPRESSION := (NUMBER | GROUP) (OPERATOR EXPRESSION)?
GROUP := "(" EXPRESSION ")"
Con esa gramática, puedes construir un analizador de descenso recursivo en un santiamén.
Una expresión regular equivalente es REALMENTE difícil de escribir, porque las expresiones regulares generalmente no tienen un soporte muy bueno para la recursión.
Otro buen ejemplo es la ingestión de JSON. He visto a gente tratar de consumir JSON con expresiones regulares, y es INSANE. Los objetos JSON son recursivos, por lo que solo piden gramáticas regulares y analizadores sintácticos de descenso recursivo.
Hmmmmmmm ... Al mirar las respuestas de otras personas, creo haber respondido la pregunta equivocada.
Lo interpreté como "¿cuándo debería usar una expresión regular simple, en lugar de un analizador completo?" mientras que la mayoría de la gente parece haber interpretado la pregunta como "¿cuándo deberías lanzar tu propio esquema de validación ad hoc de carácter por personaje, en vez de usar una expresión regular?"
Dada esa interpretación, mi respuesta es: nunca.
De acuerdo ... una edición más.
Voy a ser un poco más indulgente con el esquema de rollo propio. Solo ... no lo llames "análisis sintáctico": o)
Creo que una buena regla general es que solo debe usar primitivas de coincidencia de cadenas si puede implementar TODA su lógica con un solo predicado. Me gusta esto:
if (str.equals("DooWahDiddy")) // No problemo.
if (str.contains("destroy the earth")) // Okay.
if (str.indexOf(";") < str.length / 2) // Not bad.
Una vez que sus condiciones contienen predicados múltiples, entonces ha comenzado a inventar su propio lenguaje de validación de cadenas ad hoc, y probablemente debería simplemente buscar y estudiar algunas expresiones regulares.
if (str.startsWith("I") && str.endsWith("Widget") &&
(!str.contains("Monkey") || !str.contains("Pox"))) // Madness.
Las expresiones regulares realmente no son tan difíciles de aprender. En comparación con un lenguaje de funciones completas como C # con docenas de palabras clave, tipos primitivos y operadores, y una biblioteca estándar con miles de clases, las expresiones regulares son absolutamente simples. La mayoría de las implementaciones de expresiones regulares admiten alrededor de una docena de operaciones (dar o recibir).
Aquí hay una gran referencia:
http://www.regular-expressions.info/
PD: como bonificación, si alguna vez quieres aprender a escribir tus propios analizadores (con lex / yacc, ANTLR, JavaCC u otras herramientas similares), aprender expresiones regulares es una gran preparación, porque las herramientas generadoras de analizadores usan muchas de los mismos principios.
[Estamos] evaluando la acción de un encabezado de soap y tomando decisiones sobre eso
Nunca use expresiones regulares o análisis de cadenas básicas para procesar XML. Todos los lenguajes de uso común en este momento tienen soporte XML perfectamente bueno. XML es un estándar engañosamente complejo y es poco probable que su código sea correcto en el sentido de que analizará correctamente todas las entradas XML bien formadas, e incluso si lo hace, está perdiendo el tiempo porque (como se acaba de mencionar) cada idioma en el uso común tiene soporte XML. No es profesional usar expresiones regulares para analizar XML.
Para responder a su pregunta, en general, el uso de expresiones regulares debe minimizarse ya que no son muy legibles. A menudo puede combinar el análisis sintáctico de cadenas y las expresiones regulares (quizás en un ciclo) para crear una solución mucho más simple que las expresiones regulares solamente.
Creo que la forma más fácil de saber cuándo usar expresiones regulares y cuándo no, es cuando su búsqueda de cadenas requiere una instrucción IF / THEN o cualquier cosa que se parezca a esta o aquella lógica, entonces necesita algo mejor que una simple comparación de cadenas, que es donde Regex brilla.
Cuando su transformación requerida no es básica, pero todavía es conceptualmente simple.
no hay razón para sacar Regex si está haciendo un reemplazo de cadena recta, por ejemplo ... es más fácil simplemente usar la cuerda.
por otro lado, una regla compleja con muchos condicionales o casos especiales que tomarían más de 50 caracteres de expresiones regulares puede ser una pesadilla para mantener luego si no la escribe explícitamente
Estoy de acuerdo con lo que dijo el benjismith, pero quiero elaborar un poco. Para sintaxis muy simples, el análisis básico de cadenas puede funcionar bien, pero también lo pueden hacer los regexes. Yo no los llamaría excesivos. Si funciona, funciona: ve con lo que encuentres más simple. Y para el análisis de cadenas de moderado a intermedio, una expresión regular suele ser el camino a seguir.
Tan pronto como comiences a encontrar que necesitas definir una gramática, es decir, un complejo análisis sintáctico de cadenas, regresa al uso de algún tipo de máquina de estados finitos o lo que prefieras lo más rápido que puedas. Regexes simplemente no escala bien, para usar el término libremente. Se vuelven complejos, difíciles de interpretar e incluso incapaces.
He visto al menos un proyecto en el que el uso de expresiones regulares siguió creciendo y creciendo y pronto tuvieron problemas para insertar nuevas funcionalidades. Cuando finalmente llegó el momento de hacer una nueva versión principal, descartaron todas las expresiones regulares y siguieron la ruta de un analizador gramatical.
La expresión regular puede ser
- Más fácil de entender
- expresar más claramente la intención
- mucho más corto
- más fácil de cambiar / adaptar
En algunas situaciones, todas esas ventajas se lograrán usando expresiones regulares, en otras solo se lograrán algunas (la expresión regular no es realmente fácil de entender, por ejemplo) y en otras situaciones la expresión regular es más difícil de entender, ofusca la intención, más tiempo y difícil de cambiar
Cuantas más (y posiblemente otras) ventajas obtengo de la expresión regular, es más probable que las use.
Posible regla general: si la comprensión de la expresión regular le llevaría minutos a alguien que esté algo familiarizado con las expresiones regulares, entonces no desea usarla (a menos que el código "normal" sea aún más intrincado ;-).
Hm ... todavía no hay una regla general, lo siento.
Siempre usaré una expresión regular a menos que sea algo muy simple, como dividir una secuencia separada por comas. Si creo que existe la posibilidad de que algún día las cadenas se vuelvan más complicadas, probablemente comenzaré con una expresión regular.
No me suscribo a la opinión de que las expresiones regulares son difíciles o complicadas. Es una herramienta que todo desarrollador debe aprender y aprender bien. Tienen una gran variedad de usos, y una vez aprendido, este es exactamente el tipo de cosas de las que nunca más tendrás que preocuparte.
Los regexes rara vez son exagerados: si la coincidencia es simple, también lo es la expresión regular.