【问题标题】:Avoid extra matches from Regex_search避免来自 Regex_search 的额外匹配
【发布时间】:2018-12-12 14:40:08
【问题描述】:

对 c++ 正则表达式库非常陌生。

我们正在尝试解析一行

*10 abc

我们想将此行解析/拆分为两个标记:

10
abc

我尝试了多种方法,例如 regex_search,但我确实得到了 3 个匹配项。第一个匹配是整个匹配,第二个,第三个是子序列匹配。我的问题是

我们怎样才能从上面的字符串中只得到两个匹配项(10 和 abc)。我尝试过的快照:

#include <regex>
#include <iostream>

int main() {
  const std::string t = "*10 abc";
  std::regex rgxx("\\*(\\d+)\\s+(.+)");
  std::smatch match;
  bool matched1 = std::regex_search(t.begin(), t.end(), match, rgxx);
  std::cout << "Matched size " << match.size() << std::endl;

  for(int i = 0 ; i < match.size(); ++i) {
    std::cout << i << " match " << match[i] << std::endl;
  }
}

输出:

Matched size 3
0 match *10 abc
1 match 10
2 match abc

0 匹配是我不想要的。

我也愿意使用 boost 库/正则表达式。谢谢。

【问题讨论】:

  • 正则表达式对于这样一个简单的解析来说太过分了。只需跳过第一个字符,复制到第一个空格实例,跳过空格,然后复制其余部分。正确使用std::string 只需大约四行代码。

标签: c++


【解决方案1】:

您的代码本身并没有什么问题。零匹配只是匹配正则表达式模式的整个字符串。如果您只想要两个捕获的术语,则只需打印第一个和第二个捕获组:

const std::string t = "*10 abc";
std::regex rgxx("(\\d+)\\s+(.+)");
std::smatch match;
bool matched1 = std::regex_search(t.begin(), t.end(), match, rgxx);
std::cout << "Matched size " << match.size() << std::endl;

for (int i=1; i < match.size(); ++i) {
    std::cout << i << " match " << match[i] << std::endl;
}

Matched size 3
1 match 10
2 match abc

因此,这里的教训是匹配数组中的第一个条目(索引为零)将始终是整个字符串。

【讨论】:

  • 我知道我之前提到的那个教训。我想知道有什么办法不让整个字符串在匹配数组中?
  • 我不知道,因为这就是 API 的工作方式。但是,我不认为有太多的性能损失。相反,捕获组是正则表达式 API 可能需要做更多工作的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-09
  • 2016-12-24
  • 1970-01-01
  • 2020-02-10
  • 2012-01-26
  • 2015-05-22
  • 2016-12-21
相关资源
最近更新 更多