确定 C++11 正则表达式匹配的位置

Determining the location of C++11 regular expression matches

如何有效地确定捕获组在搜索字符串中的位置?获取整场比赛的位置很容易,但我看不出有什么明显的方法可以找到第一个以外的捕获组。

这是一个简化的示例,假设 "a*" 和 "b*" 是复杂的正则表达式,对 运行 来说是昂贵的。

#include <iostream>
#include <regex>
#include <string>
using namespace std;

int main()   
{
    regex matcher("a*(needle)b*");
    smatch findings;
    string haystack("aaaaaaaaneedlebbbbbbbbbbbbbb");

    if( regex_match(haystack, findings, matcher) )
    {
        // What do I put here to know how the offset of "needle" in the 
        // string haystack?

        // This is the position of the entire, which is
        // always 0 with regex_match, with regex_search
        cout << "smatch::position - " << findings.position() << endl;

        // Is this just a string or what? Are there member functions
        // That can be called?
        cout << "Needle - " << findings[1] << endl;
    }

    return 0;
}

如果有帮助,我在 Coliru 中构建了这个问题:http://coliru.stacked-crooked.com/a/885a6b694d32d9b5

在 72 小时过去并且没有更好的答案出现之前,我不会将此标记为并回答。

在问这个之前我假设 smatch::position 没有我关心的参数,因为当我阅读 cppreference 页面时 "sub" 参数显然不是匹配容器的索引.我认为它与"sub"字符串和整个匹配的偏移值有关。

所以我的答案是:

cout << "Needle Position- " << findings.position(1) << endl;

任何对此设计的解释,或我的思路可能导致的其他问题,我们将不胜感激。

根据documentation,您可以通过match[n].firstmatch[n].second访问指向捕获文本开头和结尾的迭代器。要获取开始和结束索引,只需使用 haystack.begin().

进行指针运算
if (findings[1].matched) {
    cout << "[" << findings[1].first - haystack.begin() << "-"
                << findings[1].second - haystack.begin() << "] "
                << findings[1] << endl;
}

除了主要比赛(索引 0)外,捕获组可能捕获也可能不捕获任何东西。在这种情况下,firstsecond 将指向字符串的末尾。

我还演示了sub_match对象的matched属性。虽然在这种情况下没有必要,但一般来说,如果要打印捕获组的索引,则有必要先检查捕获组是否匹配。