Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Regex: escludere parola da pattern

389 views
Skip to first unread message

Joe

unread,
Oct 20, 2017, 6:42:30 AM10/20/17
to
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! :)

Aqua...@despammed.com

unread,
Oct 20, 2017, 8:58:15 AM10/20/17
to
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/

Joe

unread,
Oct 20, 2017, 9:28:55 AM10/20/17
to
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! :)

Joe

unread,
Oct 20, 2017, 10:58:52 AM10/20/17
to
Non quoto tutto quello già scritto, riporto invece un
particolare della documentazione di tin, preso dal file
sopra linkato:
-------------------------
from=pattern From:
Tin converts the contents of the From-header to an
old-style e-mail address, i.e. ''so...@body.example (John
Doe)'' instead of ''John Doe <so...@body.example>'',
before trying to match the patterns in the filter rule.
That way a rule tailored to to match the full from
header "jsm...@ac.example (John Smith)" will still work
when John posts with a different newsreader which uses
"John Smith <jsm...@ac.example>".
-----------------------------------------------------

Questo per dire che se si sta cercando di intercettare
nel campo from:

paolino qualcosino <qualcosa...@example.net>

e allo stesso si vuole escludere dal filtro

paolino paperino <paper...@example.net>

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

Joe

unread,
Oct 22, 2017, 6:33:22 PM10/22/17
to
Joe <J...@e.invalid> wrote:
>
> 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

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
0 new messages