代码之家  ›  专栏  ›  技术社区  ›  Mason Wheeler

是否有Delphi标准函数用于转义HTML?

  •  26
  • Mason Wheeler  · 技术社区  · 14 年前

    我有一个报告,它应该接受一个网格控件并生成HTML输出。网格中的一列可以显示多个值中的任何一个,或者 <Any> . 当然,当输出到HTML时,结果是空白的。

    我可能会写一些程序来使用StringReplace将其转换为 &lt;Any&gt; 所以它可以正确地显示这个特定的案例,但我认为在RTL中的某个地方可能有一个已经过测试并且做得对。有人知道我在哪里能找到它吗?

    7 回复  |  直到 8 年前
        1
  •  18
  •   Andreas Rejbrand    14 年前

    我99%确信RTL中不存在这样的函数(截至Delphi2009年)。当然,然而,编写这样一个函数是微不足道的。

    更新

    httputil.htmlescape是您需要的:

    function HTMLEscape(const Str: string): string;
    

    我不敢在这里发布代码(很可能是侵犯版权),但程序非常简单。它将“<”、“>”、“&”和“”编码为 &lt; , &gt; , &amp; &quot; . 它还将字符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 + '&lt;';
          '>': result := result + '&gt;';
          '&': result := result + '&amp;';
          '"': result := result + '&quot;';
        else
          result := result + Data[i];
        end;
    
    end;
    
    function HTMLEncode2(Data: string):string;
    begin
      Result:=
        StringReplace(
        StringReplace(
        StringReplace(
        StringReplace(
          Data,
          '&','&amp;',[rfReplaceAll]),
          '<','&lt;',[rfReplaceAll]),
          '>','&gt;',[rfReplaceAll]),
          '"','&quot;',[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
    
        2
  •  13
  •   da-soft    14 年前

    这似乎是一个小的竞赛:)这里还有一个实现:

    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('&lt;');
          '>': Encode('&gt;');
          '&': Encode('&amp;');
          '"': Encode('&quot;');
        else
          result[iPos] := Data[i];
          Inc(iPos);
        end;
      SetLength(result, iPos - 1);
    end;
    

    更新1:最初更新提供的代码不正确。

    更新2:时间:

    HTMLEncode :   2286508597
    HTMLEncode2:   3577001647
    HTMLEncode3:    361039770
    
        3
  •  3
  •   Stijn Sanders    14 年前

    我通常只使用以下代码:

    function HTMLEncode(Data:string):string;
    begin
      Result:=
        StringReplace(
        StringReplace(
        StringReplace(
        StringReplace(
        StringReplace(
          Data,
          '&','&amp;',[rfReplaceAll]),
          '<','&lt;',[rfReplaceAll]),
          '>','&gt;',[rfReplaceAll]),
          '"','&quot;',[rfReplaceAll]),
          #13#10,'<br />'#13#10,[rfReplaceAll]);
    end;
    

    (版权所有?它的 open source )

        4
  •  2
  •   ErvinS    14 年前

    单位httpapp有一个称为htmlencode的函数。它还具有其他与HTML/HTTP相关的功能。

        5
  •  1
  •   Tuncay Göncüoğlu    8 年前

    我不知道它是在哪个Delphi版本中引入的,但是 System.NetEncoding 单位有:

    TNetEncoding.HTML.Encode
    TNetEncoding.HTML.Decode
    

    功能。朗读 here . 您不再需要外部库。

        6
  •  0
  •   rihar    9 年前

    用这种方式替换特殊字符怎么样?

        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;
    
        7
  •  0
  •   SuperNova    8 年前

    我的函数将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;