Newsgroup: it.comp.lang.javascript
Titolo: [?] RegExp - negare

Torno sull'argomento perché sò dde coccio!
Richiesta: tutti i tag img che non hanno settato alt.
Niente da fare...
Ho letto un po' di tutorial e ho trovato il ?! che dovrebbe negare, ma
sembra ignorarlo (c#, ma la sintassi dovrebbe essere la stessa).
es. <img[^>]+(?!alt)> da quel che ho capito dovrebbe prendere i tag img
senza alt, invece me li prende tutti!
Dove sbaglio?
Per ora ho risolto nel replace verificando se nel match c'è un alt, se non
c'è aggiungo alt=\"\", ma è una soluzione che non mi piace.
Grazie
-- 
"E' l' ignoranza che crea l'intolleranza
 di gente cieca e senza coscienza"
									  S.S.S.

 !s.match(/<img[^>]+(alt) ecc
Sì, una cosa è la richiesta pratica, un'altra è capire come funziona.
Il problema pratico che ho è: ho in mano una stringa contenente l'intero
html che il server sta inviando al client.
Questa stringa la passo ad una classe che, inserendo un filtro al Response,
sistema per xhtml (rimuove id all'head, rimuove border a img etc etc).
Mi sono reso conto che quel furbone di 
asp.net
 se setto a un controllo
Image un alt="" me lo rimuove bellobbbello (e poi xhtml si incazza perché
vuole obbligatoriamente un tag alt, anche se alt="" è assolutamente
contemplato per immagini non "importanti").
Allora volevo aggiungere alla mia classe per xhtml un'altra regexp che dice
"localizza tutti i tag img senza alt e aggiungilo". Da qua il delirio...
Per il caso pratico alla fine ho risolto così (è in c# ma la logica per chi
sa javascript/regexp mi sembra chiarissima):
		internal static string SingolImgAddAlt(Match m) {
			//in match ho il tag img, non sono riuscito a negare manco morto...
			return
(m.ToString().IndexOf("alt")==-1?m.ToString().Substring(0,m.ToString().Length-2)+"
alt=\"\"/>":m.ToString());
		} //SingolImgAddAlt
		internal string ImgAddAlt(string I) {
			//non sono riuscito a negare (img senza alt) => tutto il tag, poi uso
indexOf nel MatchEvaluator
			Regex R=new Regex("(<img[^>]+>)",RegexOptions.IgnoreCase); 
			string ris=R.Replace(I,new MatchEvaluator(SingolImgAddAlt));
			return ris;
		} //ImgAddAlt
		//che poi chiamerò con
		OutputFinale=this.ImgAddAlt(OutputFinale);
Ossia: al ImgAddAlt recupera tutti i tag img e li passa al MatchEvaluator
il quale se è già presente alt (testato con un banale IndexOf) restituisce
la stringa pari pari, altrimenti lo aggiunge.
Così al volo non mi viene in mente come negare (tuo esempio) ed ottenere
comunque il risultato.....
E comunque sono interessato a capire questa negazione nelle regexp perché
in molti casi mi tornerebbe utile (finora pensavo semplicemente che non si
potesse, e quindi risolvevo con barbatrucchi tipo quello sopra).
Magari se (a questo "se" occorre farsi una toccatina) e quando tornerà Zer0
avrà info in proposito...
-- 
"That until there is no longer first class
And second class citizens of any nation
Until the colour of a man's skin
Is of no more significance than the colour of his eyes
Me say war"
B.M.

 bicchier d'acqua.
Eppoi, dico io, se non considerasse il ?! non dovrebbe comportarsi come si
comporta (ossia ignorando completamente tutto ciò che sto negando), ma
dovrebbe trattarlo come normale carattere (e quindi non restituirmi nulla,
visto che non troverebbe nulla con dentro ?!, oppure far casini con il ?
[zero o 1 volta il precedente, o il minimo per sub-espressione etc]).
Invece sembrerebbe ignorare (e quindi sta interpretando in qualche modo
questo ?!).
-- 
"Affacciati affacciati benedici, guardaci
 guardaci...guardaci!
 Tanto sono quasi duemila anni che stai a guardare!"
									    E.B.

 o il js non implementa l'asserzione negativa
Giusto per essere ultracertissimi (dato che io l'ho testato lato server =>
c# => mamma M$), hai ovviamente provato con javascript e un browser Gecko,
vero? (ti sto quasi offendendo, scusa... :-))
-- 
"Emancipate yourselves from mental slavery;
None but ourselves can free our minds"
									    B.M.

 fine, di baci saziami :-)
:-D
-- 
"Ti sei salvato
 o sei entrato in banca pure tu?"
									    A.V.

 s.match(/<img[^>]+>/) && ! s.match(/<img[^>]+alt[^>]+>/)
Sì, ma dovrei rivedere la logica. Attualmente fa un replace dove come
secondo parametro chiama una function per effettuare la sostituzione, col
doppio match come dovrei fare? (risultato richiesto: aggiungere alt=\"\" se
non presente nei tag img, data una stringa contenente l'intero html che sta
inviando al browser).
Dovrei giocarci un po', ma la curiosità maggiore era proprio questo ?! che
non funziona, e che tutte le reference di regexp indicano.


 e quando tornerà Zer0 avrà info in proposito...
Nel tuo caso:
<img[^>]+(?!alt)>
La parte iniziale (<img[^>]+) ti prende tutto fino a > escluso, compreso
eventuale attributo "alt".
Una regexp del tipo:
<img (?!alt)
dovrebbe farti il corretto match di negazione sulle stringhe seguenti:
<img alt="" />
<img />
-- 
ZER0 
~ You don't have to be crazy to be a webmaster. But it helps.

 <img />
Uhm...sicuro? Perché avevo provato di tutto...
Io ho una stringa che contiene l'intero html...sei sicuro che con una
stringa del tipo <img/><a.../><img alt="prova"/> non mi metchi allora
<img/><a.../><img   ?
-- 
"Ho smesso di fumare.
 Vivrò una settimana di più.
 E in quella settimana pioverà a dirotto"
									    W.A.

 Uhm...sicuro? 
Certo, Tommaso. Eventualmente prova, e poi chiedimi se sono sicuro. :)
La differenza sta nel fatto che non c'è il [^>]+ precedente, quindi il
negative lookhead funziona.
La prima stringa non ti viene matchata, la seconda sì.
Va da sè che non ti è di alcuna utilità pratica nel tuo caso, ma era per
spiegarti il comportamento (visto che era ciò che chiedevi).
-- 
ZER0 
~ Il computer e' una macchina progettata per velocizzare e automatizzare
gli errori.

 spiegarti il comportamento (visto che era ciò che chiedevi).
Eggià...quindi nel mio caso l'unica strada è quella che ho seguito io?
(match dei tag img e verifica successiva, nel matchevaluator, della
presenza o meno dell'attributo alt)?


 Eggià...quindi nel mio caso l'unica strada è quella che ho seguito io?
No, ce ne sono diverse, di cui almeno una - di quelle che mi vengono in
mente ora su due piedi - tramite un'unica regexp.
Lasciando perdere la negazione, puoi giocare con i match e gli or, in modo
tale da sostiture tramite replace, gli attributi alt con sè stessi laddove
esistono, e con stringa vuota laddove non ci sono. E' possibile fare un
giochetto del genere proprio in virtù del fatto che non devi impostare una
stringa specifica, bensì una stringa vuota.
-- 
ZER0 
~ Io non soffro di pazzia, ne godo ogni minuto.
(I don't suffer from insanity, I enjoy every minute of it)

 mente ora su due piedi - tramite un'unica regexp.
Ecco...e adesso che hai creato l'acquolina in bocca che fai, lasci sbavare?


 Ecco...e adesso che hai creato l'acquolina in bocca che fai, lasci sbavare?
No, da brava personcina quale sono ti ho dato anche la "ricetta" da
seguire. :)
Ti ho scritto quel che devi fare, e cosa devi usare; adesso non ho il tempo
di farti la "pappa"; ma sono convinto che con le indicazioni di cui prima
puoi farcela benissimo da solo.
In caso negativo, proverò a fare qualche codice di prova io in serata.
P.S.
Sono stato fuori ufficio dal 2 giugno fino ad ora, ho un po' di cose da
riprendere, e soprattutto ho da imprecare contro le portlet.
-- 
ZER0 
~ "Sai che ogni volta che vedo un tramonto mi girano i coglioni perché
è passato un'altro giorno."

 riprendere, e soprattutto ho da imprecare contro le portlet.
Eh ho visto che eri scomparso, spero per vacanza...
[CODICE]
		#region ImgAddAlt
		internal static string SingolImgAddAlt(Match m) {
			return
(m.ToString().IndexOf("alt")==-1?m.ToString().Substring(0,m.ToString().Length-2)+"
alt=\"\"/>":m.ToString());
		} //SingolImgAddAlt
		internal string ImgAddAlt(string I) {
			Regex R=new Regex("(<img[^>]+>)",RegexOptions.IgnoreCase); 
			string ris=R.Replace(I,new MatchEvaluator(SingolImgAddAlt));
			return ris;
		} //ImgAddAlt
		#endregion
Da chiamarsi nel Filter con
 OutputFinale=this.ImgAddAlt(OutputFinale); //OutputFinale=intero output
html che sta inviando al client


 Eh ho visto che eri scomparso, spero per vacanza...
Ahimé no, per lavoro (escluso il ponte del 2 giugno).
-- 
ZER0 
~ Un computer e' fondamentalmente stupido.
Non fa cio' che vuoi che faccia, ma cio' che gli dici di fare.
Solo, e' uno stupido dannatamente veloce.