Extração de texto (PEG vs Regex)
Ao automatizar navegadores, você frequentemente encontra dados “bagunçados”: texto com formatação inconsistente, erros de digitação ou vários tipos de informação misturados na mesma string.
Enquanto JavaScript e Lua dependem de expressões regulares (Regex) para essa tarefa, o mecanismo Janet do Guida inclui um mecanismo integrado de Parsing Expression Grammar (PEG). PEGs são uma alternativa poderosa a Regex e tornam extrações complexas mais fáceis de ler, escrever e manter.
O problema com Regex
Seção intitulada “O problema com Regex”Regex é excelente para padrões simples, mas rapidamente fica ilegível quando lida com estruturas complexas ou aninhadas.
Imagine extrair o preço e o ID de um produto de uma string confusa como "Item: SuperWidget (ID: 98765) - Only $49.99 today!".
JavaScript (Regex)
Seção intitulada “JavaScript (Regex)”const text = "Item: SuperWidget (ID: 98765) - Only $49.99 today!";
// Regex é densa e depende de grupos capturados por índiceconst 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}`);}Isso funciona, mas a regex é frágil. Se o formato mudar um pouco, ela falha; modificá-la exige raciocínio cuidadoso sobre grupos, escapes e quantificadores.
A abordagem Janet (PEG)
Seção intitulada “A abordagem Janet (PEG)”O módulo peg do Janet permite construir parsers por composição. Em vez de uma única string enorme e críptica, você define uma gramática como um dicionário de regras legíveis.
Janet (PEG)
Seção intitulada “Janet (PEG)”(def text "Item: SuperWidget (ID: 98765) - Only $49.99 today!")
# Definir uma gramática limpa e composicional(def product-grammar (peg/compile ~{:id-rule (sequence "(ID: " (capture (some :d)) ")") :price-rule (sequence "$" (capture (some (choice :d "."))))
# A regra principal varre o texto procurando nossas regras :main (any (choice :id-rule :price-rule 1))}))
# Executar a gramática contra o texto(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 que PEGs são melhores para dados web
Seção intitulada “Por que PEGs são melhores para dados web”- Legibilidade: regras têm nome (
:id-rule,:price-rule) e podem referenciar umas às outras. Você não precisa decifrar uma regex de 50 caracteres. - Composição: parsers complexos podem ser montados a partir de regras menores e testadas.
- Sem ambiguidade: diferente de Regex, PEGs não fazem backtracking do mesmo modo imprevisível. Elas correspondem exatamente ao que você define, tornando desempenho e comportamento mais previsíveis.
- Estruturas de dados: o módulo
pegdo Janet pode construir arrays e dicionários diretamente na etapa de parse, em vez de retornar apenas strings planas.
Quando usar cada um?
Seção intitulada “Quando usar cada um?”- Use JavaScript/Lua (Regex) para validações simples, como verificar se uma string parece um e-mail.
- Use Janet (PEG) quando precisar extrair várias partes relacionadas de um bloco de texto confuso ou quando a formatação do site alvo variar bastante.