【问题标题】:Why does my regular expression grab the EOLN as well?为什么我的正则表达式也会抓取 EOLN?
【发布时间】:2020-03-11 03:49:48
【问题描述】:

我正在尝试编写一个批处理文件来自动批量编辑某些 Pascal 源。我有源文件,偶尔会有这样的一行:

     //{## identifier} Inc (Index) ; { a comment }    // another comment

我想将它们全部更改为:

     {$ifdef identifier} Inc (Index) ; { a comment }    // another comment {$endif}

下面是我正在使用的测试批处理文件。

:: File TestRXRepl.bat
:: ===================     

@echo     //{##   identifier} Inc (Index) ; { a comment }    // another comment >t.pas
@set "FindRegExp=(\ *)\/\/\{\#\#\ *([a-z,0-9,_]+)\}(\ *)(.*)"
@set "ReplRegExp=\1{$ifdef \2}\3\4 {$endif}"

rxrepl --file t.pas --output t.out --search "%FindRegExp%" --replace "%ReplRegExp%"
@type t.pas
@type t.out

正则表达式应该是:

  • 捕获前导缩进(第 1 组)
  • 匹配//{##
  • 跳过所有空格
  • 捕获标识符(第 2 组)
  • 匹配}
  • 捕获源代码缩进(第三组)
  • 从那时起捕获源行到行尾(第 4 组)

除了行尾处理外,一切正常。第 4 组应该捕获从源代码行开始到行尾的所有内容,但它似乎 include 行尾,结果是{endif} 被写入下一个行,即我得到:

{$ifdef identifier} Inc (Index) ; { a comment }    // another comment
{$endif}

而不是:

{$ifdef identifier} Inc (Index) ; { a comment }    // another comment {$endif}

我使用的工具是RXRepl。它有一个选项--eol,听起来可能很有用,但我无法通过使用它来改变行为。

(注释)

  • 我知道这两个结果在语法上都是正确的,但这不是 点;-)
  • 第 3 组和第 4 组可以合并。
  • 它不处理其他空白字符。
  • 我知道,有更经典的方式来匹配标识符。

欢迎提出使其更优雅的建议,以及使其正常工作的建议。

【问题讨论】:

  • 如果你在(.*\S)作为第四组结束比赛是否有效?或者(\N*) 可能会起作用,以另一种方式匹配.,不包含换行符...您的文件是否有DOS(CR/LF)或Unix(仅限LF)换行符?问题可能与换行格式有关...
  • 靶心。两者都有效。平台是 Windows,文件是 CRLF 分隔的。喜欢这样回答吗?
  • 是的,会的!我想知道在正则表达式的开头添加(*CRLF) 是否也会有所帮助...pcre.org/current/doc/html/pcre2pattern.html#newlines 但是如果\N 有效,这意味着 DOTALL 有效,所以不,我认为这不会有帮助。我会尽快写一个答案!

标签: regex pcre


【解决方案1】:

问题似乎是您的. 与换行符匹配,这意味着 PCRE2_DOTALL 选项有效。 (我不知道为什么会出现这种情况,rxrepl 可能总是默认设置该选项。)

解决此问题的一种可能方法是使用 \S character type 将正则表达式匹配中的第 4 组结束与 (.*\S) 匹配,这将匹配任何不是空格的字符,并且将排除换行符.

但解决此问题的最佳方法可能是使用the \N sequence,手册中将其描述为:

\N 转义序列与未设置PCRE2_DOTALL 时的“.”元字符含义相同,但设置PCRE2_DOTALL 不会改变\N 的含义。

因此,只需将(\N*) 用于匹配中的第 4 组,将匹配当前匹配的所有内容,但尾随换行符除外。

在您的脚本中,只需更新这一行:

@set "FindRegExp=(\ *)\/\/\{\#\#\ *([a-z,0-9,_]+)\}(\ *)(\N*)"

【讨论】:

    猜你喜欢
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    • 2010-09-22
    相关资源
    最近更新 更多