2009-02-05 35 views
11

Tengo un conjunto de cadenas con números incrustados en ellas. Se ven algo así como/cal/long/3/4/145: 999 o/pa/metrics/CosmicRay/24: 4: bgp: EnergyKurtosis. Me gustaría tener un analizador de expresiones que seaAlternativas a expresiones regulares

  • Fácil de usar. Con algunos ejemplos, alguien debería ser capaz de formar una nueva expresión. Quiero que los usuarios finales puedan formar nuevas expresiones para consultar este conjunto de cadenas. Algunos de los usuarios potenciales son ingenieros de software, otros son probadores y algunos son científicos.
  • Permite restricciones en los números. Algo como '/ cal/long/3/4/143: #> 100 & < 1110' para especificar que un prefijo de cadena con '/ cal/long/3/4/143:' y luego un número entre (100,1110) se espera.
  • Admite '|' y . Entonces, la expresión '/ cal/(long | short)/3/4/' coincidiría '/ cal/long/3/4/1: 2' y '/ cal/short/3/4/1: 2 '.
  • Tiene una implementación de Java disponible o sería fácil de implementar en Java.

Ideas alternativas interesantes, podrían serle útiles. También estoy entreteniendo la idea de simplemente implementar el subconjunto de expresiones regulares que necesito más las restricciones numéricas.

Gracias!

+1

Esto es lo que las expresiones regulares fue diseñado. – mmcdole

+1

No entiendo muy bien por qué quieres una alternativa a las expresiones regulares. Si pudieras explicar eso, tal vez nos ayudaría a dar una buena respuesta. Mi sugerencia es simplemente usar el subconjunto de expresiones regulares que se ajuste a sus necesidades. – skiphoppy

+0

Ah; Lo entiendo. # 2 en su lista está más allá de los límites de los motores de expresiones regulares más comunes. :) – skiphoppy

Respuesta

4

Me inclino a estar de acuerdo con Rex M, aunque su segundo requisito de restricciones numéricas complica las cosas. A menos que solo permitiera restricciones muy básicas, no conozco una forma de expresarlo de manera sucinta en una expresión regular. Si existe tal forma, ignore el resto de mi respuesta y siga las otras sugerencias aquí. :)

Es posible que desee considerar un generador de analizador sintáctico - cosas como el clásico lex y yacc.No estoy muy familiarizado con las opciones de Java, pero aquí está una lista:

http://java-source.net/open-source/parser-generators

Si usted no está familiarizado, el enfoque estándar habría que crear primero una lexer que convierte sus cadenas en tokens. Luego, pasaría esos tokens a un analizador sintáctico que les aplicaría su gramática y arrojaría algún tipo de resultado.

En su caso, imagino que el analizador resultante es una combinación de una expresión regular y condiciones adicionales. Para su ejemplo de restricción numérica, podría darle la expresión regular \/cal/long/3/4/143:(\d+)\ y una restricción para aplicar a la primera agrupación (la parte \d+) que requiere que el número se encuentre entre 100 y 1100. Luego, debe aplicar el RE a sus cadenas para candidatos, y aplicar la restricción a esos candidatos para encontrar sus partidos.

Es un enfoque bastante complicado, así que espero que haya una manera más simple. Espero que eso te dé algunas ideas, al menos.

+0

Es un enlace útil. ¡Gracias! –

7

¡No hay razón para reinventar la rueda! El núcleo de un motor de expresión regular se basa en una sólida base de las matemáticas y la informática; la razón por la que seguimos utilizándolos hoy es que son principalmente sólidos y no se mejorarán en el futuro previsible.

Si encuentra o crea un lenguaje de análisis alternativo que solo cubra un subconjunto de las posibilidades de Regex, rápidamente tendrá un usuario que le pedirá un concepto que pueda expresarse en Regex, pero su sabor simplemente lo dejará. ¡Dedique su tiempo a resolver problemas que no han sido resueltos en su lugar!

+18

Las expresiones regulares son matemáticamente sanas y rápidas. Pero * chupan * realmente duro en términos de facilidad de uso y mantenibilidad. Son pura maldad en ese sentido. Es por eso que hay una razón para reinventar. –

+3

@BT que se puede decir para cualquier idioma que no esté familiarizado con la persona que lo dice. –

+8

No estoy de acuerdo. Regex es, por lo menos, extremadamente conciso y difícil de leer. Esto es algo de opinión, creo, pero los aprendí, los desaprendí, los volví a aprender. –

0

En realidad, lo que ha descrito es el Java Pattern Matcher. Lo cual pasa a usar Regex como su idioma.

+0

Por lo que puedo decir, no hay forma de ampliar o cambiar la gramática que usa Pattern. –

+0

No entiendo por qué querrías, pero deberías ser capaz de extraer vars en el patrón, eso lo extendería. Java Pattern Matcher es una de las herramientas RegEx más eficientes que existen. Hay demasiadas cosas malas que cambiar en Java para meterse con uno de los grandes. – WolfmanDragon

2

Desafortunadamente, no todos los programadores (incluido yo) estamos tan familiarizados con RegEx como deberían. Esto a menudo significa que terminamos escribiendo nuestra propia lógica de análisis de cadenas donde RegEx podría habernos servido bien.

Esto no siempre es malo. En algunos casos, es posible escribir un DSL (una clase, un conjunto cohesivo de métodos) que sea más elegante y legible y que satisfaga las necesidades precisas de su dominio problemático. El problema es que puede llevar docenas de iteraciones destilar el problema en una DSL que es simple e intuitiva. Y solo si el DSL se usará ampliamente en la aplicación o en una comunidad grande, este problema está garantizado. No escriba una solución elegante a un problema que solo aparece esporádicamente.

+1

No escuché el término DSL en este contexto antes. Eso ha llevado a algunos google útiles. ¡Gracias! –

4

La restricción de Java es grave. Recomendaría usar combinadores de análisis, pero deberá traducir las ideas a Java utilizando clases en lugar de funciones. Hay muchos, muchos artículos disponibles sobre este tema; uno de los más fáciles de abordar es Graham Hutton's Higher-Order Functions for Parsing. El enfoque de Hutton hace que sea especialmente fácil decidir si tiene éxito o no en función de las condiciones, como la magnitud de un número, como lo muestra en su ejemplo.

0

Si va a seguir la ruta del analizador, consulte Sistema de análisis GOLD. A menudo es una mejor opción que algo como YACC, una apariencia más limpia que las expresiones regulares puras, y es compatible con Java.

http://goldparser.org/about/how-it-works.htm