Visualizzazione dei risultati da 1 a 3 su 3
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    26

    Regex avanzata: Iteratore greedy (troppo greedy?)

    Sto facendo una regex che deve essere utilizzata per un parser di WikiText.
    E' la seguente:
    (?<Level>=+)[ \t]*(?<Name>.*?)[ \t]*\k<Level>(?<Text>(\r|\r\n|\n|.)*)(?!(\r|\r\n|\n)( ?<Check>=+)[ \t]*.*[ \t]*\k<Check>)

    Quindi dovrebbe questo testo dovrebbe essere matchato così:

    codice:
    == Sezione 1 ==
    testo bla bla bla 
    
    === Sezione 2 ===
    testo sottosezione bla bla bla
    Quindi i capturing groups dovrebbero essere:
    • Match 1: gruppo <Level>: ==
    • Match 1: gruppo <Name>: Sezione 1
    • Match 1: gruppo <Text>: testo bla bla bla
    • Match 2: gruppo <Level>: ===
    • Match 2: gruppo <Name>: Sezione 2
    • Match 2: gruppo <Text>: testo sottosezione bla bla bla
    • Match


    Invece viene matchato così:

    codice:
    == Sezione 1 ==
    testo bla bla bla
    
    === Sezione 2 ===
    testo sottosezione bla bla bla
    In cui è colorato tutto con lo stesso colore, quindi è un unico match.
    Il gruppo <Level> è "==", <Name> è "Sezione 1" e <Text> è
    codice:
    testo bla bla bla
    
    === Sezione 2 ===
    testo sottosezione bla bla bla"
    L'ultimo gruppo (l'espressione (\r|\r\n|\n)(?<Check>=+)[ \t]*.*[ \t]*\k<Check>) contenuta nel negative lookahead l'ho messa apposta per evitare l'espansione del (\r|\r\n|\n|.)*, infatti (\r|\r\n|\n)(?<Check>=+)[ \t]*.*[ \t]*\k<Check> matcha un header, però comunque l'iteratore greedy si espande più del dovuto. Qualcuno mi può aiutare a risolvere questa situzione? Grazie

    (Forse può sembrare tutto troppo complicato però con l'aiuto di qualche programma tipo RegexBuddy diventa molto più semplice)

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    26
    Per semplificare la cosa, prendete pure in considerazione questa regex:

    =+[ \t]*.*?[ \t]*=+(\r|\r\n|\n|.)*(?!=+[ \t]*.*[ \t]*=+)

    E' uguale alla prima ma senza capturing groups e senza \k<name>

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    26
    Risolto
    A chiunque possa servire:
    (?<Level>^={2,6})[ \t]*(?<Name>.*?)[ \t]*\k<Level>(?<Text>((\r?\n|.)(?!(?<Check>^={2,6})[ \t]*.*[ \t]*\k<Check>))*)|^((\r?\n|.)(?!(?<First>^={2,6})[ \t]*.*[ \t]*\k<First>))*


    Matcha perfettamente tutte le sezioni di MediaWiki.
    L'errore stava nell'inserire il negative lookahead fuori del gruppo ripetuto, mentre doveva stare (logicamente) all'interno: ad ogni ripetizione deve capire se il carattere evalutato precede un nuovo header.

    I gruppi Check e First servono solo all'espressione per regolarsi sulla definizione di un header

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.