【问题标题】:Replace last occurences of string in lines between two strings替换两个字符串之间的行中最后出现的字符串
【发布时间】:2019-11-27 12:18:08
【问题描述】:

我正在尝试构建一个正则表达式,使我能够替换两个特定字符串之间多行上的最后一个逗号。

示例文本:

BEGIN_MESSAGE_MAP(SomeForm, BaseForm)
    ON_COMMAND(CID_ButtonAction, OnButtonAction)
    ON_NOTIFY_EX(CID_Notify, 0, OnNotify)
END_MESSAGE_MAP()

期望的输出:

BEGIN_MESSAGE_MAP(SomeForm, BaseForm)
    ON_COMMAND(CID_ButtonAction, &ThisClass::OnButtonAction)
    ON_NOTIFY_EX(CID_Notify, 0, &ThisClass::OnNotify)
END_MESSAGE_MAP()

替换一行的最后一个逗号很简单:

找到(,)([^,]*?)$

并替换为(?1,&ThisClass\:\:\2)

我还能够构建一个匹配 BEGIN_MESSAGE_MAPEND_MESSAGE_MAP 之间所有内容的正则表达式。

(?<=BEGIN_MESSAGE_MAP)(.*\R)*(?=END_MESSAGE_MAP)

问题是 - 我如何将这两个放在一起,以便我只能在这两个字符串之间进行替换?

【问题讨论】:

  • PCRE,很抱歉省略了,添加了一个标签。

标签: regex replace pcre


【解决方案1】:

您可以使用此正则表达式进行搜索:

(?:^\h*BEGIN_MESSAGE_MAP|(?!\A)\G)(?:.*\R)+?.*\K(,\h*)(?=(?:.*\R)+^END_MESSAGE_MAP)

并将其替换为:

$1&ThisClass::

RegEx Demo

正则表达式详细信息:

  • \G 在前一个匹配的末尾或第一个匹配的字符串的开头断言位置。通过将负前瞻 (?!\A) 我们确保 \G 在字符串的开头不匹配。
  • \K 重置报告匹配的起点。
  • 最后(?=...) 的前瞻条件是确保我们前面有END_MESSAGE_MAP

【讨论】:

  • 不完全,它在演示中完美运行,但在 Notepad++(使用 boost 正则表达式作为引擎)中,由于某种原因它只匹配第一次出现
  • 正如您提到的 pcre 这个 reged 正在使用 pcre 功能。确保您开启了多行模式
  • 根据我在文档中读到的内容,Notepad++ 应该通过使用 boost regex 作为引擎来支持 PCRE。问题似乎是 Notepad++ 中无法启用的 /g 标志。
  • 与答案中的问题完全相同,只有第一次出现被捕获并替换......当您在 regex101.com 中禁用 /g 时,您可以复制我在 Notepad++ 中看到的内容跨度>
  • /g 在这里是必需的,因为我们使用\G 捕获多个事件。我没有Notepad++,但我相信他们会有办法启用全局模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-26
相关资源
最近更新 更多