Newsgroup: it.comp.lang.perl
Titolo: problema con regex

Salve, vedo che da molto tempo nessuno scrive più su questo NG, ma ci provo.
 
Ho realizzato un piccolo bot irc (che sostanzialmente funziona..), e vorrei 
far si che se riceve una query con un indirizzo web, risponda per le rime 
all'user incriminato.
 
Il messaggio che arriva dal server irc ha questo formato;:
 
:liftman!~
loca...@pincopallo.it
 PRIVMSG bot :
http://pippo.it
 
 
dove liftman è il nick di chi invia la query, bot è il nick del bot e 
http.... sarebbe lo spam da perseguire :-)
 
la regex che ho cercato di fare è questa:
 
/:(.*)\!.*\s(PRIVMSG)\s($nick)\s:(http.*)/
 
e che per quel poco che ci ho capito, dovrebbe stare per /:(una stringa di 
qualsiasi lunghezza)!un'altra stringa spazio PRIVMSG spazio il nick del bot 
(la variabile è correttamente valorizzata all'inizio del listato) (spazio ed 
una stringa di qualsiasi lunghezza, che inizi per http)/
 
ho provato altre varie combinazioni, per esempio sostituendo le "\s" con "." 
o i ":" con "\:" (non ho ben capito se i : sono considerati normali 
caratteri alfanumerici...)
 
-- 
Fri(END), Boyfri(END), Girlfri(END), Bestfri(END). Everything has an END 
except...Fam(ILY)! It Has 3 Letters that say I LOVE YOU 
 


 
I due punti sono considerati normali caratteri
 
Comunque la scriverei cosi supponendo che tu abbia in $line la stringa 
da valutare
 
 
my @a=$line=~/:(.*)\!.*PRIVMSG\s+(\S+)\s+:(\S+)/;
if (@a) { #ora in @a hai i valori
 
}
 
 
almeno se il tuo problema è il match della regexp
 
 
Esiste anche una forma piu abbreviata usando $_ e $1,$2,...
ma questa mi sembra sufficientemente chiara
 
PRIVMSG non l' ho messo tra () in quanto inutile se e' costante
 
 
 
 
 

/:(.*)\!.*PRIVMSG\s+(\S+)\s+:(\S+)/;
 
purtroppo così com'era matchava praticamente tutti i messaggi del server che 
non fossero un VERSION o un PING o un NOTICE, oltretutto non controllava sei 
il messaggio era indirizzato al bot, e se c'era un url nella stringa, però 
avvalendomi del tuo esempio, ragionandoci un poco, ed andando per 
(ulteriori) tentativi, ho partorito questa:
 
 /:(.*)\!.*(PRIVMSG).($nick).*(http|www.*)$/i
 
che pare risolvere il problema, o almeno non mi pare abbia manifestato 
controindicazioni.
Grazie per l'aiuto!


 controindicazioni.
 
come non detto... :-)
Così com'è funzionava con qualsiasi url che iniziasse con  "http" (anche 
https), ma non se l'url è tipo "
www.pincopallo.it
", quindi ho modificato la 
regex così:
 
 /:(.*)\!.*(PRIVMSG).($nick).*(?:http|www).*$/i
 
adesso pare funzionare come volevo, sempre salvo complicazioni :)
Non è propriamente un argomento semplicissimo da capire, forse tra 30 
anni.... :)



 
Se una singola regexpr e' complicata da scrivere si possono anche 
scrivere delle if con delle regexp in cascata
Non e' obbligatorio fare il tutto con una singola regexp
 
 

 Non e' obbligatorio fare il tutto con una singola regexp
 
si certo, ma alla fine sarebbe stato molto più complesso (credo..) dato che 
comunque dall'espressione dovevo determinare che l'argomento da processare 
fosse un messaggio del server (PRIVMSG) chi lo scriveva,( 
:pincopallo!~host@domain) che lo scrivesse al bot ($nick) , e che il 
messaggio contenesse un url, tutte in questa esatta sequenza.
 
Se il bot funzionasse su un sistema windows, con il mirc scripting avrei 
risolto in 5 minuti, dato che esistono degli appositi identificatori che 
semplificano di molto questo genere di lavori, il perl anche se enormemente 
più potente, è anche enormemente più complesso da padroneggiare.
