Extraction de texte (PEG ou regex)
Lorsque vous automatisez des navigateurs, vous rencontrez souvent des données « sales » : texte formaté de façon incohérente, contenant des fautes ou mélangeant plusieurs types d’informations dans une même chaîne.
JavaScript et Lua s’appuient sur les expressions régulières (regex) pour ce travail, tandis que le moteur Janet de Guida inclut un moteur Parsing Expression Grammar (PEG) intégré. Les PEG sont une alternative puissante aux regex qui rend l’extraction de texte complexe plus facile à lire, écrire et maintenir.
Le problème des regex
Section intitulée « Le problème des regex »Les regex sont excellentes pour les motifs simples, mais deviennent vite illisibles lorsqu’il faut gérer des structures complexes ou imbriquées.
Imaginez l’extraction du prix et de l’ID d’un produit depuis une chaîne désordonnée comme "Item: SuperWidget (ID: 98765) - Only $49.99 today!".
JavaScript (regex)
Section intitulée « 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}`);}Cela fonctionne, mais la regex reste fragile. Si le format change légèrement, elle échoue, et la modifier demande de la gymnastique mentale.
L’approche Janet (PEG)
Section intitulée « L’approche Janet (PEG) »Le module peg de Janet permet de construire des parseurs par composition. Au lieu d’une énorme chaîne cryptique, vous définissez une grammaire comme dictionnaire de règles lisibles.
Janet (PEG)
Section intitulée « 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))))Pourquoi les PEG sont utiles pour les données web
Section intitulée « Pourquoi les PEG sont utiles pour les données web »- Lisibilité : les règles sont nommées (
:id-rule,:price-rule) et peuvent se référencer entre elles. Vous n’avez pas à décoder une regex de 50 caractères. - Composition : vous pouvez construire des parseurs complexes en combinant de petites règles testées.
- Absence d’ambiguïté : contrairement aux regex, les PEG ne backtrackent pas de la même façon imprévisible. Ils correspondent exactement à ce que vous leur demandez, avec des performances plus prévisibles.
- Structures de données : le module
pegde Janet peut construire des structures complexes, tableaux ou dictionnaires, directement depuis l’étape de parsing, au lieu de renvoyer seulement des chaînes plates.
Quand utiliser quoi ?
Section intitulée « Quand utiliser quoi ? »- Utilisez JavaScript/Lua avec regex pour les validations simples, par exemple vérifier si une chaîne ressemble à une adresse e-mail.
- Utilisez Janet avec PEG lorsque vous devez extraire plusieurs morceaux de données liés depuis un bloc de texte désordonné, ou lorsque le format du site cible varie beaucoup.