Newsgroup: it.comp.os.linux.iniziare
Titolo: Regex: escludere parola da pattern

Ciao a tutti,
sto cercando il modo di creare un "filtro" che
vada ad intercettare tutte le righe similari ad
un certo pattern.
Però il pattern in questione matcha anche una stringa
precisa che invece non voglio filtrare.
 
Mi spiego con un esempio:
 
input.txt
----------
paolino paperino
mario rossi
giuseppe bianchi
paolino pomodorino
martin smith
leo fugacci
paolino tavolino
marika tempi
paolino cucchiaino
-------------------
 
il filtro deve intercettare solo:
-------------------
paolino pomodorino
paolino tavolino
paolino cucchiaino
-------------------
 
Ora, esistono REGEX di diverso tipo, nel mio caso vorrei
utilizzare questa regex con il filtro del mio newsreader:
http://www.tin.org/filtering.txt
 
 
Dal manuale non sono riuscito a capire quale tipo di REGEX
siano supportate, forse POSIX... ma non riesco a capire di
preciso cercando in rete, magari qualcuno di voi qui lo sa
altrimenti provo a chiedere direttamente agli sviluppatori
del newsreader.
 
Allora, il pattern generico da considerare sarebbe il
seguente:
 
'paolino\s\b.*ino\b'
 
Ad esempio se lo do in pasto a grep applicato al file di
input, ne esce la lista con tutti i "paolino ...".
Ma in voglio che in questo output non sia presente "paperino".
 
Quindi servirebbe una regex che intercetti il pattern, ma
che allo stesso tempo escluda la stringa in cui la ripetizione
di caratteri:
 
".*"
 
non coincida con la parola:
 
"paperino"
 
Ho visto che ad esempio le regexp Perl compatibili supportano
questo scopo. E il seguente comando filtrerebbe correttamente:
 
grep -P 'paolino\s\b(?!paperino).*ino\b' input.txt
 
 
Nota:
se mettessi solo \b(?!paper).*ino\b il filtro sarebbe più debole
e non verrebbe filtrato ad esempio un ipotetico: "papercavolino",
che invece sarebbe logicamente da buttare.
 
Il punto è il seguente:
- se tin supporta le regex perlcompatibili, allora la regex sopra
  è ok
- altrimenti dovrei generare una regex POSIX o quel che è in grado
  di fare la stessa cosa.
 
Avreste qualche idea su come scriverla?
E se sia possibile, perchè non è mica detto...
 
 
Grazie in anticipo e scusate la lunghezza...
Non solo: abbiate pietà per il tristissimo
esempio paperonico!!  :_((  :DD
 
Ci leggiamo!    :)


grep -P 'paolino\s(?!paperino)' ex.txt
 
 
 
-- 
Lime and limpid green, a second scene
A fight between the blue you once knew
Floating down, the sound resounds
Around the icy waters underground
 
http://fuffologia.wordpress.com/
 


No, perchè non è coerente col pattern da filtrare che
grosso modo è fatto così:
 
paolino|spazio|qualcosa|ino
 
Se aggiungi al tuo input ad esempio "paolino rossi",
questo verrà filtrato, mentre invece andrebbe lasciato
passare...
 
Invece col mio comando funziona:
 
grep -P 'paolino\s\b(?!paperino).*ino\b'
 
perchè in pratica esclude "paperino" non da "tutto lo scibile",
ma solo da tutti i nomi che terminano in "ino".
 
 
Però sia io che te abbiamo preso la scorciatoia offerta
dalle regex Perl-compatibili.
E se invece togliessi l'opzione "-P" al comando grep, come
riscriveresti la regex?
 
Nota inoltre:
a me non interessano eventuali soluzioni con "grep -v" ad
esempio. Mi interessa solo la REGEX in se, da poter dare
in pasto al filtraggio del newsreader tin.
 
Ciao e comunque grazie!  :)


 
Innanzitutto bisogna ragionare sulle stringhe
che tin converte così:
 
qualcosa...@example.net
 (paolino qualcosino)
paper...@example.net
 (paolino paperino)
 
 
Ho fatto una prova pratica aggiungendo nel ~/.tin/filter
la seguente regola:
--------------------
comment=Paperomorfi
group=qua.qua.qua
case=0
score=kill
from=.*(?!paperopoli).*
po...@example.net
\s\(paolino\s\b(?!paperino).*ino\b\).*
-----------------------------------------------------------------------------
 
 
Fatto questo bisogna impostare in ~/.tin/tinrc l'opzione
wildcard=1
 
Questo attiva il filtraggio via REGEX invece che via WILDMAT.
Siccome di default il filtraggio è in formato wildmat, bisgna
convertirlo a mano... Roba da poco:
nel wildmat si usa "*" per intercettare qualsiasi roba,
nel regex invece si usa ".*"
 
Fatto questo si può avviare tin ed entrando nel gruppo
"qua.qua.qua" ecco che i vari messaggi unread dei vari
"paolino qualcosino" sono più presenti... Ma al tempo
stesso resta visibile il nostro "paolino paperino".
Good job!
 
In conclusione tin supporta il formato regex che include
quella REGEX stile perl-compatibile, non sono sicurissimo
che si dica così, d'altra parte di "REGEX flavors" ve ne
sono un bordello (v.di tabella in fondo a questa pagina):
https://www.regular-expressions.info/reference.html
 
 
Direi che è tutto...
Per chi non usa tin forse servirà a poco, ma spero sia
utile un po' a tutti in qualche modo...
 
Alla prossima!  :)
E ancora mille scuse per gli esempi coi paperi...  :DD

 
https://www.regular-expressions.info/reference.html
 
 
Per completezza, questo è specificato nel man, mi era
sfuggito, il tipo di regex preciso è appunto "PCRE":
----------------------------
Wildcard matching (wildcard)
Allows you to select how tin matches strings. The default is 0 and
uses the wildmat notation, which is how this has traditionally been
handled. *Setting this to 1 allows you to use perl(1) compatible*
*regular expressions pcre(3) (see also perlre(1) and pcrepattern(3)).*
You will probably want to update your filter file if you use this
regularly. NB: Newsgroup names will always be matched using the
wildmat notation.
-----------------
 
 
Per quello che rigarda il filtraggio di cui avevo
bisogno si può impostare in tin anche attraverso
lo scoring, senza REGEX complicate come quella
sopra:
 
-------
group=*
case=0
score=kill
from=John\s+.*son\b
 
group=*
case=0 
score=hot
from=John\sSamuelson\b
----------------------
 
Questo elimina i messaggi provenienti da tutti gli
utenti contenenti:
 
John qualcosason
 
Ma non quelli che contengono:
 
John Samuelson