【问题标题】:Regex to match multiple MBCS strings on any line正则表达式匹配任意行上的多个 MBCS 字符串
【发布时间】:2013-10-01 20:11:46
【问题描述】:

我正在寻找一个正则表达式来仅匹配 C++ 项目中的 MBCS 字符串。这些是包含在双引号中的字符串,没有L"..."_T("...") 说明符。任何代码行都可以有多个引号。字符串可以包含不应结束匹配的转义子字符串。以下是几个例子:

"This is a MBCS string"; // "This is a MBCS string" match
_T("This is maybe a unicode string"); // no match
L"This is a unicode string"; // no match
"These both" + "should match"; // "These both" and "should match" match
"This is a \"quoted\" string"; // "This is a \"quoted\" string" match

我有一个正则表达式,可以使用负回溯(?<!#include )(?<!_T\()(?<!\\)(?<!L)\"(.*?)\"(?<!\\\") 处理所有这些问题,但它变得更加复杂。它开始在一行上混合字符串类型出现问题。

_T("Maybe this") + "is a match"; // "is this" match but instead would match ") + "
do_something(_T("This doesn't match")) + do_something("but this does match"); // "but this does match" match but instead it matches ")) + do_something("

我怎样才能让正则表达式在 _T("")L"" 单词上不匹配,但仍然匹配它们以吃掉结尾引号而不将其作为匹配项返回?

编辑:这个正则表达式 (?:_T\(\"[^\"]+\"\).*?|L\"[^\"]+\".*?)*(?<!#include )(?<!_T\()(?<!L)(?<!\\)\"(.*?)\"(?<!\\\") 几乎可以完成这项工作,但还有一个测试用例失败了,我最初没想过要包括在内。

_T("don't match this") + _T("or this"); // shouldn't match anything, matches ") + _T("

【问题讨论】:

  • 你不能全部匹配然后过滤掉那些以L_T(开头的吗?
  • 如果您的字符串格式正确,我会提取每个(?:L|_T\s*\(\s*)?"(?:[^\"]+|\\")*" 字符串,然后检查它是否在开始引号之前有前缀。
  • 是的,这绝对是一个想法。我想知道是否有一种简单的方法来提出正确的正则表达式,但是当我通过一些真实文件运行它时,这看起来越来越难了。

标签: c++ regex string


【解决方案1】:

您实际上可能会匹配 _TL 部分,以便在之前的匹配中使用它们:

(?:_T\(\"[^\"]+\"\).*?|L\"[^\"]+\".*?)?(?<!#include )(?<!_T\(|L|\\)\"(.*?)\"(?<!\\\")

我还缩短了负面的后视。

regex101 demo

【讨论】:

  • 行得通,谢谢!为了将它与 Python 一起使用,我不得不扩展缩短后的外观,它只在固定长度的外观上运行,所以我最终得到了以下(?:_T\(\"[^\"]+\"\).*?|L\"[^\"]+\".*?)?(?&lt;!#include )(?&lt;!_T\()(?&lt;!L)(?&lt;!\\)\"(.*?)\"(?&lt;!\\\")
  • @Kyle 哦,好吧,可以理解,这意味着尽管您应该仍然可以使用 (?&lt;!L|\\) 而不是 (?&lt;!L)(?&lt;!\\) :)
  • 这是我提出的问题的一个很好的解决方案,但是我在原始示例中错过了一个带有两个转义字符串 _T("test"), _T("case") 的大型测试用例。它与非捕获组不匹配,并在两个字符串之间命中), _T(,这是错误的。据我所知,可以捕获零个字符或主要捕获,但这会通过在大多数行上不捕获任何内容并引发异常来破坏 Python 替换。捕获任何字符串@tripleee 并检查正则表达式外部是否是 MBCS 字符串可能是最简单的。
  • @Kyle 你也有连续的“错误匹配”(如果我可以这样称呼)?您可以将? 变成*,这样可以跳过更多。您还可以测试不同的案例here(我已经在其中添加了两个连续T("...") 的案例)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-12
  • 2020-06-12
  • 1970-01-01
  • 2014-10-11
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
相关资源
最近更新 更多