java - utilizar - Alternativas a las expresiones regulares
parentesis en expresiones regulares java (7)
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 sea
- 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 . Así que la expresión ''/ cal / (long | short) / 3/4 / '' coincidiría ''/ cal / long / 3/4/1: 2'' así como ''/ cal / short / 3/4/1: 2 ''.
- Tiene una implementación Java disponible o sería fácil de implementar en Java.
Interesantes ideas alternativas serían útiles. También estoy entreteniendo la idea de simplemente implementar el subconjunto de expresiones regulares que necesito más las restricciones numéricas.
¡Gracias!
¡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 encuentras o creas un lenguaje de análisis alternativo que solo cubre un subconjunto de las posibilidades que Regex puede ofrecer, rápidamente pedirás a un usuario un concepto que pueda expresarse en Regex, pero que simplemente dejará de tener sabor. ¡Dedique su tiempo a resolver problemas que no han sido resueltos en su lugar!
En realidad, lo que describes es Java Pattern Matcher. Lo cual pasa a usar Regex como su idioma.
Lamentablemente, no todos los programadores (yo incluido) están 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.
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, como el clásico lex y yacc. No estoy muy familiarizado con las opciones de Java, pero aquí hay una lista:
http://java-source.net/open-source/parser-generators
Si no está familiarizado, el enfoque estándar sería crear primero un lexer que convierta 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 sintáctico resulta en una combinación de 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 porción /d+
) que requiere que el número se encuentran entre 100 y 1100. Luego, debe aplicar el RE a sus cadenas para los candidatos, y aplicar la restricción a esos candidatos para encontrar sus coincidencias.
Es un enfoque bastante complicado, así que espero que haya una manera más simple. Espero que eso te dé algunas ideas, al menos.
La restricción de Java es severa. Recomendaría utilizar los 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 High-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.
Si vas a ir a la ruta del analizador, echa un vistazo a GOLD Parsing System. 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://java-source.net/open-source/parser-generators y http://catalog.compilertools.net/java.html contienen catálogos de herramientas para esto. Compare también la pregunta de ¿ Cómo puedo analizar el código para construir un compilador en Java? .