【问题标题】:CharInSet bulk conversions when migrating from Delphi 2007从 Delphi 2007 迁移时的 CharInSet 批量转换
【发布时间】:2015-10-02 00:26:07
【问题描述】:

我们正在将一些项目从 Delphi 2007 转移到 XE8,并收到以下警告(有数百个):

[dcc32 Warning] X.PAS(1568): W1050 WideChar reduced to byte char in set expressions.  Consider using 'CharInSet' function in 'SysUtils' unit.`

我突然想到,其中许多都是这种形式

if x in ['1','2','3'] then

需要转换成的

if CharInSet(x, ['1','2','3']) then

这看起来可能有某种正则表达式类型的搜索和替换可用于批量执行这些操作。

谁能想到批量转换这些的方法?

【问题讨论】:

  • 这将是作为 IDE 专家编写的一个不错的重构,也许可以将其贡献给 GExperts。我认为与其使用正则表达式,不如使用像 Castalia 解析器这样的解析器更有意义。毕竟,“x in y”的任何使用,其中 x 的类型是 Char 并且 y 是一组 char,无论是否是文字,都可以从重构中受益。
  • 我还不确定CharInSet 是前进的方向
  • 但是是的,您可以编写一个正则表达式来捕获这些。为什么不尝试这样做呢?是什么阻碍了你。编写一个正则表达式来查找 in 的这些用法。测试它是否只找到需要更改的实例。然后使用捕获来执行替换。有很多工具可用。在提交之前仔细审查。
  • @DavidHeffernan,上次我检查 (XE8) CharInSet 的性能时,它的优化出奇的好。
  • @LURD 我最后一次检查 2009-10Seattle 如果你有一个常量集,CharInSet 的性能仍然要慢得多,因为 CharInSet 总是使用内存位运算,而“集合中的元素”可以使用算术运算没有常量集的内存访问。顺便说一句:编译器为if c in ['a'..'z'] then stmtcase c of 'a'..'z': stmt; end; 生成相同的代码。只要您的集合中没有非 ascii 字符,c in charset 仍然有效。只有宽字符警告必须被禁用。

标签: delphi unicode migration delphi-xe8


【解决方案1】:

这可以通过 IDE 中的搜索/替换来完成。

以下在 XE4 中适用于我。

  • 搜索:

    if {[a-z]} in \[{{'[0-9]+'\,? ?}+}\] then
    

    如果您想匹配超过一个字符长度的变量,请考虑使用一些量词,例如[a-z]+

  • 替换为:

    if CharInSet\(\0, \[\1\]\) then
    

请注意,IDE 使用 {} 表示组,使用 \0\1 ... 作为替换占位符。

Embarcadero Regular Expressions reference for Delphi XE4


IDE 正则表达式搜索:

结果单位:


您可能还会发现this question 对进一步参考很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    相关资源
    最近更新 更多