我有一个报告,应该采取网格控制并生成HTML输出。网格中的一列可以显示任意数量的值,或<Any>
。当它输出到HTML时,当然它最终会变成空白。是否有用于转义HTML的Delphi标准函数?
我可能会写一些例程来使用StringReplace将其转换为<Any>
,以便它能够正确显示此特定情况,但是我认为RTL中可能有一个已经过测试并且正确的RTL。任何人都知道我在哪里可以找到它?
我有一个报告,应该采取网格控制并生成HTML输出。网格中的一列可以显示任意数量的值,或<Any>
。当它输出到HTML时,当然它最终会变成空白。是否有用于转义HTML的Delphi标准函数?
我可能会写一些例程来使用StringReplace将其转换为<Any>
,以便它能够正确显示此特定情况,但是我认为RTL中可能有一个已经过测试并且正确的RTL。任何人都知道我在哪里可以找到它?
我99%确定这样的函数在RTL中不存在(截至Delphi 2009)。当然 - 然而,编写这样一个函数是微不足道的。
更新
HTTPUtil.HTMLEscape是你正在寻找:
function HTMLEscape(const Str: string): string;
我不敢在这里发布的代码(侵犯版权,可能),但例程非常简单。它编码 “<”, “>”, “&”,和 “””来<
,>
,&
,和"
,还替换字符#92,#160 ..#255为十进制码,例如\
。
后者步骤是不必要的,如果该文件是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.
输出是
532031
801969
我通常只使用此代码:
function HTMLEncode(Data:string):string;
begin
Result:=
StringReplace(
StringReplace(
StringReplace(
StringReplace(
StringReplace(
Data,
'&','&',[rfReplaceAll]),
'<','<',[rfReplaceAll]),
'>','>',[rfReplaceAll]),
'"','"',[rfReplaceAll]),
#13#10,'<br />'#13#10,[rfReplaceAll]);
end;
(?版权是open source)
这看起来* *比一个简单的循环慢:对于I:= 1到长度(Data)do case ord(Data [i])... – 2010-06-03 19:06:59
我刚刚测试了这个:嵌套StringReplace:801259滴答。单循环:532037滴答。 – 2010-06-03 19:14:55
但是,当然,最简单的循环方法将会失败,#13#10 ... – 2010-06-03 19:21:00
看来这里是一个小比赛:)这里是一个更多的实现:
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;
更新1:更新最初提供了不正确的代码。
更新2:与时代:
HTMLEncode : 2286508597
HTMLEncode2: 3577001647
HTMLEncode3: 361039770
这是一个非常好的解决方案! (虽然也许有点矫枉过正!:)) 主要的收益可能不是移动,但事实上,你不需要不断地为结果分配更多的空间。我会给你一个+1,除非它是因为它不是对实际问题的回答! :) – 2010-06-04 11:55:06
那么,我给你+1,只是因为它是一个优化的例子。 – 2010-06-04 13:00:58
(顺便说一下:你知道“内容”和“比赛”之间有细微差别吗?:)) – 2010-06-04 13:26:24
单位HTTPApp有一个称为的HTMLEncode功能。它还有其他HTML/HTTP相关功能。
正如前面已经指出的那样... – 2010-06-04 11:54:39
HTTPApp.HTMLEncode在Delphi 2009和2010中没有正确编码字符串 - http://qc.embarcadero.com /wc/qcmain.aspx?d=78903 – mjn 2013-04-11 05:50:00
怎么样的替代特殊字符的方式:
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;
在这个问题中特别询问标准函数,以便您的答案不会回答它,而不管它是否正确。 – lukelazarovic 2015-09-09 13:34:17
我的功能相结合的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;
我不知道在哪个德尔福版本,它但有,System.NetEncoding
单位有:
TNetEncoding.HTML.Encode
TNetEncoding.HTML.Decode
f unctions。阅读here。你不需要外部库了。
德尔福方式逃脱HTML ... intraweb! ;-) – LachlanG 2010-06-04 04:07:51