Extracción de texto (PEG frente a regex)
Al automatizar navegadores, con frecuencia se encuentran datos “desordenados”: texto con formato inconsistente, erratas o mezcla de distintos tipos de información en una sola cadena.
JavaScript y Lua recurren a expresiones regulares para esta tarea, pero el motor Janet de Guida incluye un motor integrado de Parsing Expression Grammar (PEG). Las PEG son una alternativa potente a regex que hace que la extracción compleja de texto sea más fácil de leer, escribir y mantener.
El problema con regex
Sección titulada «El problema con regex»Regex es excelente para patrones simples, pero se vuelve rápidamente ilegible, casi un lenguaje de solo escritura, cuando trata estructuras complejas o anidadas.
Imagine extraer el precio y el ID de un producto desde una cadena desordenada como "Item: SuperWidget (ID: 98765) - Only $49.99 today!".
JavaScript (regex)
Sección titulada «JavaScript (regex)»const text = "Item: SuperWidget (ID: 98765) - Only $49.99 today!";
// Regex is dense and relies on capturing groups that are extracted by indexconst regex = /\\(ID:\\s*(\\d+)\\).*?\\$([0-9.]+)/;const match = text.match(regex);
if (match) { const id = match[1]; const price = match[2]; g.log(`Found ID: ${id}, Price: ${price}`);}Aunque esto funciona, la expresión regular es frágil. Si el formato cambia ligeramente, fallará, y modificarla exige gimnasia mental.
El enfoque Janet (PEG)
Sección titulada «El enfoque Janet (PEG)»El módulo peg de Janet permite construir analizadores de forma composicional. En lugar de una cadena enorme y críptica, se define una gramática como diccionario de reglas legibles.
Janet (PEG)
Sección titulada «Janet (PEG)»(def text "Item: SuperWidget (ID: 98765) - Only $49.99 today!")
# Define a clean, compositional grammar(def product-grammar (peg/compile ~{:id-rule (sequence "(ID: " (capture (some :d)) ")") :price-rule (sequence "$" (capture (some (choice :d "."))))
# The main rule scans through the text looking for our rules :main (any (choice :id-rule :price-rule 1))}))
# Run the grammar against the text(def results (peg/match product-grammar text))
(if results (do (def id (get results 0)) (def price (get results 1)) (g.log (string "Found ID: " id ", Price: " price))))Por qué las PEG son mejores para datos web
Sección titulada «Por qué las PEG son mejores para datos web»- Legibilidad: las reglas tienen nombre (
:id-rule,:price-rule) y pueden referenciarse entre sí. No hay que descifrar una cadena regex de 50 caracteres. - Composición: puede construir analizadores complejos combinando reglas pequeñas y probadas.
- Sin ambigüedad: a diferencia de regex, las PEG no retroceden del mismo modo impredecible. Coinciden exactamente con lo que se les indica, haciendo el rendimiento predecible.
- Estructuras de datos: el módulo
pegde Janet puede construir estructuras complejas, como arrays y diccionarios, directamente desde el paso de análisis, en lugar de devolver solo cadenas planas.
¿Cuándo usar cada una?
Sección titulada «¿Cuándo usar cada una?»- Use JavaScript/Lua (regex) para validaciones simples, por ejemplo comprobar si una cadena parece un email.
- Use Janet (PEG) cuando necesite extraer varias piezas de datos relacionados desde un bloque de texto desordenado, o cuando el formato del sitio objetivo sea muy variable.