gpt4 book ai didi

regex - Delphi TRegEx 反向引用损坏?

转载 作者:行者123 更新时间:2023-12-03 14:41:32 27 4
gpt4 key购买 nike

我在使用 TRegEx.replace 时遇到问题:

var
Value, Pattern, Replace: string;
begin
Value := 'my_replace_string(4)=my_replace_string(5)';
Pattern := 'my_replace_string\((\d+)\)';
Replace := 'new_value(\1)';
Value := TRegEx.Replace(Value, Pattern, Replace);
ShowMessage(Value);
end;

预期结果为 new_value(4)=new_value(5) ,而我的代码(用 Delphi XE4 编译)给出 new_value(4)=new_value()1)

使用 Notepad++,我得到了预期的结果。

使用命名组可以明确 1反向引用按字面意思处理:

Pattern := 'my_replace_string\((?<name>\d+)\)';
Replace := 'new_value(${name})';
// Result: 'new_value(4)=new_value(){name})'

替换总是那么简单(可能是零次或多次 my_replace_string ),因此我可以轻松创建自定义搜索和替换函数,但我想知道这里发生了什么。

这是我的错还是bug?

最佳答案

我可以在 Delphi XE4 中重现该错误。我在 Delphi XE5 中得到了正确的行为。

该错误存在于 TPerlRegEx.ComputeReplacement 中。我向 Embarcadero 贡献的用于包含在 Delphi XE3 中的代码使用了 UTF8String。在 Delphi XE4 Embarcadero 中,从 RegularExpressionsCore 单元中删除了 UTF8String,并用 TBytes 代替。进行此更改的开发人员似乎忽略了 Delphi 中字符串和动态数组之间的一个关键区别。字符串使用写时复制机制,而动态数组则不然。

因此,在我的原始代码中,TPerlRegEx.ComputeReplacement 可以执行 S := FReplacement,然后修改临时变量 S 以替换反向引用,而无需影响 FReplacement 字段,因为两者都是字符串。在修改后的代码中,S := FReplacement 使 S 指向与 FReplacement 相同的数组,并且在 S 中进行反向引用时> 被替换,FReplacement 也被修改。因此,第一个替换是正确的,而接下来的替换是错误的,因为 FReplacement 被破坏了。

在 Delphi XE5 中,通过用此替换 S := FReplacement 来制作正确的临时副本来修复此问题:

SetLength(S, Length(FReplacement));
Move(FReplacement[0], S[0], Length(FReplacement));

当 Delphi 2009 发布时,Embarcadero 进行了很多讨论,认为不应使用字符串类型来表示字节序列。看来他们现在犯了相反的错误,使用 TByte 来表示字符串。

我之前向 Embarcadero 推荐过的解决方案是切换到新的 pcre16 函数,该函数像 Delphi 字符串一样使用 UTF16LE。这些函数在Delphi XE发布时并不存在,但现在有了,应该使用它们。

关于regex - Delphi TRegEx 反向引用损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20970339/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com