使用 or 匹配正则表达式

Posted

技术标签:

【中文标题】使用 or 匹配正则表达式【英文标题】:Using or for matching regex 【发布时间】:2016-06-17 13:16:28 【问题描述】:

我想使用正则表达式从-afooa--bfoob- 中提取foo

我第一次尝试这个(使用boost):

std::string input = "-afooa-";
boost::regex  re("-(?:a|b)(.*)(?:a|b)-");
boost::smatch what; 
bool isMatchFound = boost::regex_match(input, what, re); 

if (isMatchFound && what.size() == 2) 
 
    std::cout << what[1];

这可行,但允许-afoob-....所以我尝试更新我的正则表达式,在阅读了正则表达式文档后,我觉得我需要一个带有“非标记括号”的或条件并最终得到这个正则表达式@987654327 @ 但随后找到了两个匹配项 "foo"""...

我做错了什么?

【问题讨论】:

作为一个选项,您可以使用-(a|b)foo\1- 请您用正则表达式类型或编程语言标记您的问题吗? @revo:完成了,但是,我想这不是我的编程语言特有的...... 您发布了一个代码块并询问了 RegEx。所以我不会错。谢谢 【参考方案1】:

您可以在第一个 (a|b) 周围使用捕获组,然后使用反向引用:

-(a|b)(.*?)\1-

请参阅regex demo。这次你会在what[2]得到结果。

在 C++ 中,声明

boost::regex  re("-(a|b)(.*?)\\1-");

我还建议使用惰性点.*? 以便将ab 之后的子字符串第一次 出现在下一个ab 中。

仅供参考:regex_match 只会匹配 full 字符串。如果您正在寻找部分匹配,请使用regex_search

为了完整性:如果你想将结果放入第 1 组(通过what[1]),你需要一个分支重置分组结构:

-(?|a(.*?)a|b(.*?)b)-

请参阅Boost regex reference 和a demo。

【讨论】:

谢谢! -(?|a(.*?)a|b(.*?)b)- 成功了。你能解释一下我原来的版本(-(?:a(.*)a|b(.*)b)-)有什么问题吗? -(?:a(.*)a|b(.*)b)- 模式匹配 -,然后是两者之一:1) a(.*)a - a 后跟除换行符之外的任何 0+ 字符,直到最后一个 a在将as 之间的子字符串捕获到第 1 组的行上,或 2) b(.*)b - b 后跟除换行符之外的任何 0+ 字符,直到捕获子字符串的行上的最后一个 b bs 之间进入第 2 组。因此,您需要检查哪个组匹配。使用分支重置时,组索引会从分支重置到分支,您将获得索引为 1 的第一个捕获组和分支 2 中具有相同索引的第二个捕获组。 感谢您的帮助、答案和正则表达式课程 ;-)【参考方案2】:

* 允许零长度匹配。您可以尝试使用+ 来要求一个或多个(因此.+ 将是一个或多个任意字符)。

【讨论】:

以上是关于使用 or 匹配正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

使用 Boost 澄清逻辑 AND 和 OR 的正则表达式匹配

正则表达式与 C# 中的 OR 条件最长匹配

正则表达式匹配非零前缀数字 *OR* 字母数字

正则表达式:如果条件发生则匹配值

正则表达式REGEXP

简化正则表达式 OR 模式