是否有用于转义HTML的Delphi标准函数?
我有一个报告,它应该接受一个网格控件并生成HTML输出。网格中的一列可以显示多个值中的任意一个,或是否有用于转义HTML的Delphi标准函数?,html,delphi,escaping,Html,Delphi,Escaping,我有一个报告,它应该接受一个网格控件并生成HTML输出。网格中的一列可以显示多个值中的任意一个,或。当然,当它被输出到HTML时,它会以空白结束 我可能会编写一些例程,使用StringReplace将其转换为Any,这样它就可以正确地显示这个特定的情况,但我认为RTL中可能有一个已经过测试并且做得很好的地方。有人知道我在哪里可以找到它吗?我99%确定RTL中不存在这样的函数(从Delphi 2009开始)。当然——然而——编写这样一个函数是微不足道的 更新 HTTPUtil.HTMLEscape
。当然,当它被输出到HTML时,它会以空白结束
我可能会编写一些例程,使用StringReplace将其转换为
Any
,这样它就可以正确地显示这个特定的情况,但我认为RTL中可能有一个已经过测试并且做得很好的地方。有人知道我在哪里可以找到它吗?我99%确定RTL中不存在这样的函数(从Delphi 2009开始)。当然——然而——编写这样一个函数是微不足道的
更新
HTTPUtil.HTMLEscape是您要寻找的:
function HTMLEscape(const Str: string): string;
我不敢在这里发布代码(可能会侵犯版权),但程序非常简单。它将“,”和“,”编码为
,
,和”
。它还将字符#92、#160..#255替换为十进制代码,例如和#92代码>
如果文件是UTF-8,则后一步是不必要的,并且也是不合逻辑的,因为更高的特殊字符,例如∮ 保留原样,同时对较低的特殊字符(如×)进行编码
更新2
根据Stijn Sanders的回答,我做了一个简单的性能测试
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.
我通常只使用以下代码:
function HTMLEncode(Data:string):string;
begin
Result:=
StringReplace(
StringReplace(
StringReplace(
StringReplace(
StringReplace(
Data,
'&','&',[rfReplaceAll]),
'<','<',[rfReplaceAll]),
'>','>',[rfReplaceAll]),
'"','"',[rfReplaceAll]),
#13#10,'<br />'#13#10,[rfReplaceAll]);
end;
函数HTMLEncode(数据:字符串):字符串;
开始
结果:=
StringReplace(
StringReplace(
StringReplace(
StringReplace(
StringReplace(
数据,
“&”,“&;”,[rfReplaceAll]),
“,”,[rfReplaceAll]),
“,”,[rfReplaceAll]),
#13#10,
13#10,[rfReplaceAll]);
结束;
(版权所有?它是)这里似乎有一个小竞赛:)这里还有一个实现:
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;
单元HTTPApp有一个名为HTMLEncode的函数。它还具有其他与HTML/HTTP相关的功能。如何替换特殊字符:
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;
My函数将for循环与字符串的最小重新分配相结合:
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;
函数HtmlEncode(常量值:字符串):字符串;
变量
i:整数;
开始
结果:=数值;
i:=1;
虽然我不知道它是在哪个delphi版本中引入的,但是有一个系统.NetEncoding
单元,它有:
TNetEncoding.HTML.Encode
TNetEncoding.HTML.Decode
功能。仔细阅读。您不再需要外部库了。从unit Soap.HTTPUtil或者对于较旧的delphi版本,您可以使用
function HTMLEscape(const Str: string): string;
var
i: Integer;
begin
Result := '';
for i := Low(Str) to High(Str) do
begin
case Str[i] of
'<' : Result := Result + '<'; { Do not localize }
'>' : Result := Result + '>'; { Do not localize }
'&' : Result := Result + '&'; { Do not localize }
'"' : Result := Result + '"'; { Do not localize }
{$IFNDEF UNICODE}
#92, Char(160) .. #255 : Result := Result + '&#' + IntToStr(Ord(Str[ i ])) +';'; { Do not localize }
{$ELSE}
// NOTE: Not very efficient
#$0080..#$FFFF : Result := Result + '&#' + IntToStr(Ord(Str[ i ])) +';'; { Do not localize }
{$ENDIF}
else
Result := Result + Str[i];
end;
end;
end;
函数HTMLEscape(const Str:string):string;
变量
i:整数;
开始
结果:='';
对于i:=低(Str)到高(Str)do
开始
案件Str[i]
'':结果:=结果+'';{不本地化}
“&”:结果:=结果+”&;{不本地化}
“'”:结果:=结果+”;{不本地化}
{$ifndefunicode}
#92,Char(160)#255:Result:=Result+''+IntToStr(Ord(Str[i]))+';';{不本地化}
{$ELSE}
//注意:效率不高
#$0080..#$FFFF:Result:=Result+''+IntToStr(Ord(Str[i]))+';';{不本地化}
{$ENDIF}
其他的
结果:=Result+Str[i];
结束;
结束;
结束;
在delphi中,您可以使用
THTMLEncoding.HTML.Encode
这看起来比简单的循环慢得多:对于i:=1到length(Data)do case ord(Data[i]),我刚刚测试了这个:Nested StringReplace:801259 ticks。单循环:532037 ticks.hmm,有趣的是,使用TStringStream还可以获得一些性能吗?主要的性能缺陷可能是对结果字符串的不断重新分配。这可以在da soft的回复中解决。但性能对OP来说根本不是问题,因此,它更像是一个有趣的旁注无论如何,千倍感谢这里的输入,我已经修改了我的HTMLEncode:一种逃避HTML的Delphi方法。。。Intraweb!;-)这是一个非常好的解决方案!(也许有点过分了!:)主要的收获可能不是移动,而是你不需要不断地为结果分配更多的空间。我会给你一个+1,除非它不是对实际问题的答案!:)嗯,我给你+1只是因为这是一个很好的优化例子。(顺便说一句:你知道“内容”和“竞赛”之间有细微的区别吗?:)当然!我对“meet”和“meat”也有类似的问题:)谢谢你的快速例行程序-我必须转换大量数据,这节省了我的时间。HTTPApp.HTMLEncode在Delphi 2009和2010中没有正确编码字符串-标准函数在这个问题中被特别询问,所以你的答案不会回答它,无论它是否正确。
function HTMLEscape(const Str: string): string;
var
i: Integer;
begin
Result := '';
for i := Low(Str) to High(Str) do
begin
case Str[i] of
'<' : Result := Result + '<'; { Do not localize }
'>' : Result := Result + '>'; { Do not localize }
'&' : Result := Result + '&'; { Do not localize }
'"' : Result := Result + '"'; { Do not localize }
{$IFNDEF UNICODE}
#92, Char(160) .. #255 : Result := Result + '&#' + IntToStr(Ord(Str[ i ])) +';'; { Do not localize }
{$ELSE}
// NOTE: Not very efficient
#$0080..#$FFFF : Result := Result + '&#' + IntToStr(Ord(Str[ i ])) +';'; { Do not localize }
{$ENDIF}
else
Result := Result + Str[i];
end;
end;
end;
THTMLEncoding.HTML.Encode