html - only - regular expression for special characters in java
¿Hay una función estándar de Delphi para escaparse de HTML? (7)
¿Qué tal la forma de reemplazar personajes especiales?
function HtmlWeg(sS: String): String;
var
ix,cc: Integer;
sC, sR: String;
begin
result := sS;
ix := pos(''/u00'',sS);
while ix >0 do
begin
sc := copy(sS,ix+4,2) ;
cc := StrtoIntdef(''$'' +sC,32);
sR := '''' + chr(cc);
sS := Stringreplace(sS, ''/u00''+sC,sR,[rfreplaceall]) ;
ix := pos(''/u00'',sS);
end;
result := sS;
end;
Tengo un informe que se supone que debe tomar un control de cuadrícula y producir resultados en HTML. Una de las columnas de la cuadrícula puede mostrar cualquiera de varios valores, o <Any>
. Cuando esto sale a HTML, por supuesto, termina en blanco.
Probablemente podría escribir alguna rutina para usar StringReplace para convertirlo en <Any>
por lo que mostraría este caso particular correctamente, pero creo que probablemente haya uno en el RTL en algún lugar que ya haya sido probado y que funcione correctamente. ¿Alguien sabe dónde podría encontrarlo?
Estoy 99% seguro de que tal función no existe en la RTL (a partir de Delphi 2009). Por supuesto, sin embargo, es trivial escribir tal función.
Actualizar
HTTPUtil.HTMLEscape es lo que estás buscando:
function HTMLEscape(const Str: string): string;
No me atrevo a publicar el código aquí (violación de derechos de autor, probablemente), pero la rutina es muy simple. Codifica "<", ">", "&" y "" "en <
>
&
y "
. También reemplaza los caracteres # 92, # 160 .. # 255 por códigos decimales, por ejemplo \
Este último paso es innecesario si el archivo es UTF-8, y también ilógico, porque los caracteres especiales más altos, como ∮, se dejan tal como están, mientras que los caracteres especiales más bajos, como ×, se codifican.
Actualización 2
En respuesta a la respuesta de Stijn Sanders, realicé una prueba de rendimiento simple.
program Project1;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils;
var
t1, t2, t3, t4: Int64;
i: Integer;
str: string;
const
N = 100000;
function HTMLEncode(const Data: string): string;
var
i: Integer;
begin
result := '''';
for i := 1 to length(Data) do
case Data[i] of
''<'': result := result + ''<'';
''>'': result := result + ''>'';
''&'': result := result + ''&'';
''"'': result := result + ''"'';
else
result := result + Data[i];
end;
end;
function HTMLEncode2(Data: string):string;
begin
Result:=
StringReplace(
StringReplace(
StringReplace(
StringReplace(
Data,
''&'',''&'',[rfReplaceAll]),
''<'',''<'',[rfReplaceAll]),
''>'',''>'',[rfReplaceAll]),
''"'',''"'',[rfReplaceAll]);
end;
begin
QueryPerformanceCounter(t1);
for i := 0 to N - 1 do
str := HTMLEncode(''Testing. Is 3*4<3+4? Do you like "A & B"'');
QueryPerformanceCounter(t2);
QueryPerformanceCounter(t3);
for i := 0 to N - 1 do
str := HTMLEncode2(''Testing. Is 3*4<3+4? Do you like "A & B"'');
QueryPerformanceCounter(t4);
Writeln(IntToStr(t2-t1));
Writeln(IntToStr(t4-t3));
Readln;
end.
El resultado es
532031
801969
La unidad HTTPApp tiene una función llamada HTMLEncode. También tiene otras funciones relacionadas con HTML / HTTP.
Mi función combina el for-loop con una reasignación mínima de la cadena:
function HtmlEncode(const Value: string): string;
var
i: Integer;
begin
Result := Value;
i := 1;
while i <= Length(Result) do
begin
if Result[i] = ''<'' then
begin
Result[i] := ''&'';
Insert(''lt;'', Result, i + 1);
Inc(i, 4);
end
else if Result[i] = ''>'' then
begin
Result[i] := ''&'';
Insert(''gt;'', Result, i + 1);
Inc(i, 4);
end
else if Result[i] = ''"'' then
begin
Result[i] := ''&'';
Insert(''quot;'', Result, i + 1);
Inc(i, 6);
end
else if Result[i] = ''&'' then
begin
Insert(''amp;'', Result, i + 1);
Inc(i, 5);
end
else
Inc(i);
end;
end;
No sé en qué versión delphi se introdujo, pero existe la unidad System.NetEncoding
que tiene:
TNetEncoding.HTML.Encode
TNetEncoding.HTML.Decode
funciones. Lea here . Ya no necesitas bibliotecas externas para eso.
Parece que aquí hay un concurso pequeño :) Aquí hay una implementación más:
function HTMLEncode3(const Data: string): string;
var
iPos, i: Integer;
procedure Encode(const AStr: String);
begin
Move(AStr[1], result[iPos], Length(AStr) * SizeOf(Char));
Inc(iPos, Length(AStr));
end;
begin
SetLength(result, Length(Data) * 6);
iPos := 1;
for i := 1 to length(Data) do
case Data[i] of
''<'': Encode(''<'');
''>'': Encode(''>'');
''&'': Encode(''&'');
''"'': Encode(''"'');
else
result[iPos] := Data[i];
Inc(iPos);
end;
SetLength(result, iPos - 1);
end;
Actualización 1: se actualizó inicialmente el código incorrecto provisto.
Actualización 2: Y los tiempos:
HTMLEncode : 2286508597
HTMLEncode2: 3577001647
HTMLEncode3: 361039770
Usualmente uso este código:
function HTMLEncode(Data:string):string;
begin
Result:=
StringReplace(
StringReplace(
StringReplace(
StringReplace(
StringReplace(
Data,
''&'',''&'',[rfReplaceAll]),
''<'',''<'',[rfReplaceAll]),
''>'',''>'',[rfReplaceAll]),
''"'',''"'',[rfReplaceAll]),
#13#10,''<br />''#13#10,[rfReplaceAll]);
end;
(derecho de autor? es de código abierto )