Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Aug 2012
    Messaggi
    91

    [regularExpression] dubbio importante

    ciao ho un grosso problema con le regular expression

    dati i file nella dir :
    codice:
    1.txt
    a
    a.*
    appppppppppj.txt
    arpiero.txt
    a.txt
    col.txt
    cool.txt
    coooooooool.txt
    il ppppp ddsa  l.txt
    kola.txt
    p2
    pall.txt
    .....
    il comando ls | grep a.*
    non mi restituisce nulla , mentre io gli sto dicendo a seguito da qualsiasi carattere ripetuto 0 o più volte

    mentre
    ls | grep "a.*" restituisce 9 risultati
    codice:
    a
    a.*
    appppppppppj.txt
    arpiero.txt
    a.txt
    il ppppp ddsa  l.txt
    kola.txt
    pall.txt


    e ls | egrep "a.{3}" restituisce 6 risultati

    codice:
    appppppppppj.txt
    arpiero.txt
    a.txt
    il ppppp ddsa  l.txt
    kola.txt
    pall.txt

    per quale motivo sono costretto a mettere il double quoting con le regular expression? quando è obbligatorio usarlo?
    perchè io impongo a grep 3 occorrenze del carattere che precede e lui mi trova ad esempio arpiero.txt che di occorrenze di r n ha solo una ?
    quando scrivo una regular expression i metacaratteri della shell perdono il loro significato no? es * nella shell significa qualsiasi stringa, mentre nella regular expression
    qualsiasi occorrenza del carattere che precede
    grazie

  2. #2
    quando scrivo una regular expression i metacaratteri della shell perdono il loro significato no?
    No. La shell non sa nulla di grep o egrep, se non fai quoting applicherà il normale globbing, espandendo * e altri caratteri magici; a grep non arriverà il tuo pattern, ma i nomi dei file già espansi dalla shell.
    Per "bloccare" il globbing devi usare gli apici singoli o doppi.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it
    Registrato dal
    Aug 2012
    Messaggi
    91
    Quote Originariamente inviata da MItaly Visualizza il messaggio
    No. La shell non sa nulla di grep o egrep, se non fai quoting applicherà il normale globbing, espandendo * e altri caratteri magici; a grep non arriverà il tuo pattern, ma i nomi dei file già espansi dalla shell.
    Per "bloccare" il globbing devi usare gli apici singoli o doppi.

    ciao , grazie della risposta : 1) se la shell non sa nulla di grep e regular expression , e se è necessario fare il quoting , a cosa serve usare la sbarra rovesciata \ davanti a caratteri come * \ . ect ????? inoltre , come si fa a far in modo che grep interpreti in modo letterale i caratteri * \ ect , senza la shell prima li espanda considerandoli metacaratteri?

  4. #4
    Quote Originariamente inviata da toni00t Visualizza il messaggio
    ciao , grazie della risposta : 1) se la shell non sa nulla di grep e regular expression , e se è necessario fare il quoting , a cosa serve usare la sbarra rovesciata \ davanti a caratteri come * \ . ect ????? inoltre , come si fa a far in modo che grep interpreti in modo letterale i caratteri * \ ect , senza la shell prima li espanda considerandoli metacaratteri?
    Il problema è che ci sono due livelli di escaping.

    Se non metti la stringa tra virgolette, la shell fa globbing a meno che i caratteri speciali non siano preceduti da \. In questo caso "passano" direttamente al comando, cosa di cui puoi avere prova facendo qualche test con il comando echo:
    codice:
    matteo@teolapkubuntu:~/py/test$ echo *
    backup.py backup.pyc
    matteo@teolapkubuntu:~/py/test$ echo \*
    *
    Tuttavia, * a sua volta ha un significato speciale nelle regex; se vuoi matchare * in una regex, deve arrivare a grep come \*, motivo per cui dovresti fare un doppio escaping, dato che sia il backslash che l'* devono essere escapati perché la shell non li tocchi:
    codice:
    matteo@teolapkubuntu:~/py/test$ echo \\\*
    \*
    In questa maniera rischi di ritrovarti con una quantità improbabile di backslash ogni volta che usi le regexp; per questo motivo, normalmente le regexp si mettono tra apici singoli, in modo che la shell non ci metta (praticamente) mano:
    codice:
    matteo@teolapkubuntu:~/py/test$ echo '*'
    *
    matteo@teolapkubuntu:~/py/test$ echo '\*'
    \*
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Utente di HTML.it
    Registrato dal
    Aug 2012
    Messaggi
    91
    ciao , grazie delle risposte , finalmente ho capito i motivi dei miei errori: c'è un ultima cosa che però non mi torna

    ho i seguenti file :
    codice:
    appppppppppj.txt
    il ppppp ddsa  l.txt
    ppppmijhij.txt
    pppppp\lk.txt
    pppppppppppppppjkjk.txt
    è assurdo , ma se do il comando ls | grep -E p"{3,5}" , me li restituisce tutti e 4 invece
    di darmi solo i file che hanno un numero di p compreso tra 3 e 5 .perchè?
    nel mio manuale , classic shell scripting o'really non ne spiega il motivo

  6. #6
    Perché ti stupisce? grep matcha sottostringhe che iniziano o finiscono in un punto qualunque della riga, di fatto la tua espressione richiede semplicemente che ci siano più di tre p di fila in un punto qualunque di ciascuna riga (e quindi non pone limite al numero massimo di p consecutive). Per fare quello che chiedi, dovresti usare una regex del tipo
    codice:
    (^|[^p])p{3,5}([^p]|$)
    (a te il capire come funziona )
    Ultima modifica di MItaly; 23-03-2014 a 19:53
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it
    Registrato dal
    Aug 2012
    Messaggi
    91
    Quote Originariamente inviata da MItaly Visualizza il messaggio
    Perché ti stupisce? grep matcha sottostringhe che iniziano o finiscono in un punto qualunque della riga, di fatto la tua espressione richiede semplicemente che ci siano più di tre p di fila in un punto qualunque di ciascuna riga (e quindi non pone limite al numero massimo di p consecutive). Per fare quello che chiedi, dovresti usare una regex del tipo
    codice:
    (^|[^p])p{3,5}([^p]|$)
    (a te il capire come funziona )
    comincia con qualsiasi carattere(non si scrive ^. ???) eccetto p
    dopo un numero di p da a 5
    finisci con qualsiasi carattere eccetto p

    perchè tutti quegli or ??

  8. #8
    Utente di HTML.it
    Registrato dal
    Aug 2012
    Messaggi
    91
    ciao ho trovato per caso questa soluzione :
    codice:
    "^([^p]*p){3,5}[^p]*$"
    funziona , ma...perchè sono obbligato a specificare il gruppo all inizio?
    dove hai imparato a scrivere quelle regex?

  9. #9
    Quote Originariamente inviata da toni00t Visualizza il messaggio
    ciao ho trovato per caso questa soluzione :
    codice:
    "^([^p]*p){3,5}[^p]*$"
    Non mi sembra che risponda a quello che chiedi, ad esempio questa regex matcha come corretta una cosa del tipo
    codice:
    apapap
    Per quanto riguarda la mia (sorry, mi ero perso il messaggio ) avevo fatto un po' di confusione a mia volta la versione corretta direi che potrebbe essere:
    codice:
    ^[^p]*p{3,5}[^p]*$
    che matcha solo stringhe che contengono da tre a cinque p incluse tra caratteri non-p.
    dove hai imparato a scrivere quelle regex?
    Esperienza sul campo, uso quotidiano di vim (dove l'uso delle regex è praticamente continuo ) e di grep.
    Amaro C++, il gusto pieno dell'undefined behavior.

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.