我尝试使用 TPerlRegEx 类用新行替换空格。
with RegExp do
begin
Subject:=Memo1.Lines.Text;
RegEx:=' ';
Replacement:='\r\n';
ReplaceAll;
Memo1.Lines.Text:=Subject;
end;
问题在于它将 \r\n 替换视为文字文本。
我尝试使用 TPerlRegEx 类用新行替换空格。
with RegExp do
begin
Subject:=Memo1.Lines.Text;
RegEx:=' ';
Replacement:='\r\n';
ReplaceAll;
Memo1.Lines.Text:=Subject;
end;
问题在于它将 \r\n 替换视为文字文本。
利用#13#10
program Project29;
{$APPTYPE CONSOLE}
uses
SysUtils, PerlRegEx;
var RegEx: TPerlRegEx;
function CStyleEscapes(const InputText:string):string;
var i,j: Integer;
begin
SetLength(Result, Length(InputText));
i := 1; // input cursor
j := 1; // output cursor
while i <= Length(InputText) do
if InputText[i] = '\' then
if i = Length(InputText) then
begin
// Eroneous quotation...
Result[j] := '\';
Inc(i);
Inc(j);
end
else
begin
case InputText[i+1] of
'r', 'R': Result[j] := #13;
'n', 'N': Result[j] := #10;
't', 'T': Result[j] := #9;
'\':
begin
Result[j] := '\';
Inc(j);
Result[j] := '\';
end;
else
begin
Result[j] := '\';
Inc(j);
Result[j] := InputText[i+1];
end;
end;
Inc(i,2);
Inc(j);
end
else
begin
Result[j] := InputText[i];
Inc(i);
Inc(j);
end;
SetLength(Result, j-1);
end;
begin
RegEx := TPerlRegEx.Create;
try
RegEx.RegEx := ' ';
RegEx.Replacement := CStyleEscapes('\t\t\t');;
RegEx.Subject := 'FirstLine SecondLine';
RegEx.ReplaceAll;
WriteLn(RegEx.Subject);
ReadLn;
finally RegEx.Free;
end;
end.
我真的很想知道为什么它没有按预期进行匹配。
文本中\
转义序列的处理在. 如果您查看代码,您会发现没有产生回车和换行字符的序列。实际上都是关于反向引用的。Replacement
TPerlRegEx.ComputeReplacement
ComputeReplacement
正则表达式的匹配阶段的处理由PCRE代码执行。但是,替换阶段是纯 Pascal 代码。并且很容易检查代码以了解它的作用。它不会按照您的想法和期望去做。
结论是您无法使用转义序列指定所需的字符。我认为您需要设计自己的规则来转义不可打印的字符并将这些规则应用到OnReplace
事件处理程序中。
编辑,因为我今天学到了一些新东西。
我前一段时间遇到了与问题相同的问题,并得出了错误的结论
.TRegEx
根本不做任何 C 风格的反斜杠转义扩展
正确的结论应该是在字符串参数
TRegEx
中没有做C风格的反斜杠转义扩展replacement
,我应该研究是否在pattern
字符串参数中做。
我知道对字符转义机制的支持因开发工具而异。
例如,C、C#、Java、Perl、PHP、Ruby、bash 等等都进行反斜杠转义扩展。
但是由于 Delphi 编译器(因为它不是 C 风格的编译器)没有。
它会将Pascal 样式的转义(如#13#10
, 或^M^J
)扩展为 CRLF。
所以我今天做了这项研究(感谢 David 指出我最初的错误),并提出了两个示例(一个在 Delphi 中,一个在 C# 中),它们的功能基本上可以做到这一点:
然后通过以下方式调用示例函数:
从两个示例的输出中,您可以看到:
RegEx
文档)RegEx
文档)建议仍然有效:
所以要么使用 Pascal 风格的转义,要么使用 Cosmin 写的C风格的反斜杠扩展函数。
附带说明:使用任何扩展功能时,您应该记住它会改变文本的含义。Delphi 用户可能不会期望 C 风格的字符串扩展。