Home

 
 
 
 
 



 
 
 
 

 
 
 

 
 
 
 
 









Blog2theMax
Il blog del team di Code Architects

L'altro giorno un nostro amico-cliente ci chiama per un problema con un controllo WinForm wordprocessor-like. Nella loro applicazione usano questo controllo anche per la capacità di importare HTML, solo che a un certo punto scoprono che il controllo va in crash se il test HTML contiene un tag IMG con attributo ALIGN e che punta a una immagine "remota", ovvero il cui URL comincia per http:// , come in questo esempio:

   <IMG SRC="http://www.somesite.com/image.jpg" ALIGN=left WIDTH=100>

Con un po' di tentativi scoprono che il problema è la presenza dell'attributo ALIGN e che il crash si può evitare se si trasforma l'HTML in questo modo:

   <DIV style="float:left"><IMG SRC="http://www.somesite.com/image.jpg" WIDTH=100></DIV>

in altre parole, occorre eliminare l'attributo ALIGN dall'interno del tag IMG e renderlo come style di un blocco DIV che racchiude il tag IMG. Questa sostituzione va fatta un attimo prima di caricare il testo HTML nel controllo, ma solo se il tag IMG contiene un attributo ALIGN e solo se l'URL dell'immagine comincia con i caratteri "http://". Il tutto è complicato dal fatto che il valore dei vari attributi può essere o non essere racchiuso tra virgolette. Insomma, un bel problemino.

Ovviamente, la soluzione sarebbe stata basata su qualche regex, ma era la prima volta che mi imbattevo in un caso di questo tipo. I problemi da risolvere erano principalmente due: come agire solo sui tag IMG contenenti un SRC remoto e come fare per "spostare" solo l'attributo ALIGN, senza toccare tutti gli altri attributi che compaiono nel tag IMG. Il primo problema lo si risolve con le cosiddette positive look-ahed assertion, ovvero il costrutto (?=...), che permette di controllare che esista una certa sottostringa a destra della regex principale, ma senza consumare caratteri per il match. Il secondo problema si risolve facilmente se si pensa a suddividere l'intero contenuto del tag IMG in tre gruppi: il gruppo pre contiene tutti i caratteri prima dell'attributo ALIGN, il gruppo align contiene il valore dell'attributo ALIGN, e il gruppo post contiene tutti i caratteri dopo l'attributo align. Ecco la soluzione in VB e C#:

   Dim search As String = "<img(?=.*src=\""?http://.*?>)(?=.*\balign=.*?>)(?<pre>[^>]*)\balign=\""?(?<align>[^ \""]+)\""?(?<post>[^>]*>)"
   Dim replace As String = "<div style=""float:${align}""><img ${pre} ${post}</div>"
   Dim result As String = Regex.Replace(htmlText, search, replace, RegexOptions.IgnoreCase Or RegexOptions.Multiline)

   string pattern = @"<img(?=.*src=\""?http://.*?>)(?=.*\balign=.*?>)(?<pre>[^>]*)\balign=\""?(?<align>[^ \""]+)\""?(?<post>[^>]*>)";
   string replace = @"<div style=""float:${align}""><img ${pre} ${post}</div>";
   string result = Regex.Replace(htmlText, search, replace, RegexOptions.IgnoreCase | RegexOptions.Multiline);

La cosa notevole non è tanto che questo problema è risolvibile con le regex - lo davo per scontato, in effetti - ma che possa essere risolto senza implementare un loop o un metodo di callback per il replace.

C# | Regex
12/8/2007 1:46:40 PM (GMT Standard Time, UTC+00:00) #  | Comments [3] | 
 
Feed di Blog2theMax
RSS 2.0 | Atom 0.2
Cerca nel blog
Archivio
<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910
Categorie

Powered by: newtelligence dasBlog 1.7.5016.2

 ©2004-2005 Code Architects S.r.l. - All rights reserved  Sign In