2

我想找到所有类似“{some text}”的东西。

我的代码是:

std::wregex e(L"(\\{([a-z]+)\\})");
    std::wsmatch m;


    std::regex_search(chatMessage, m, e);
    std::wcout << "matches for '" << chatMessage << "'\n";
    for (size_t i = 0; i < m.size(); ++i) {
        std::wssub_match sub_match = m[i];
        std::wstring sub_match_str = sub_match.str();
        std::wcout << i << ": " << sub_match_str << '\n';
    }  

但是对于这样的字符串: L"Roses {aaa} {bbb} are {ccc} #ff0000") 我的输出是:

0: {aaa}
1: {aaa}
2: aaa

而且我没有得到下一个子字符串。我怀疑我的正则表达式有问题。你们中的任何人都知道出了什么问题吗?

4

3 回答 3

5

您正在搜索一次并简单地遍历组。相反,您需要多次搜索并仅返回正确的组。尝试:

std::wregex e(L"(\\{([a-z]+)\\})");
std::wsmatch m;

std::wcout << "matches for '" << chatMessage << "'\n";
while (std::regex_search(chatMessage, m, e))
{
    std::wssub_match sub_match = m[2];
    std::wstring sub_match_str = sub_match.str();
    std::wcout << sub_match_str << '\n';
    chatMessage = m.suffix().str(); // this advances the position in the string
}

2这是第二组,即括号中的第二件事,即([a-z]+)

有关群组的更多信息,请参阅此内容。

于 2013-08-05T11:16:08.287 回答
2

正则表达式没有错,但需要反复搜索。而且无论如何,您实际上并不需要括号。

std::regex_search找到该模式的一次出现。就是这样{aaa}std::wsmatch就是这样。它有 3 个子匹配。整个字符串,外括号的内容(又是整个字符串)和内括号的内容。这就是你所看到的。

您必须regex_search再次调用字符串的其余部分才能获得下一个匹配项:

std::wstring::const_iterator begin = chatMessage.begin(), end = chatMessage.end();
while (std::regex_search(begin, end, m, e)) {
    // ...
    begin = m.end();
}
于 2013-08-05T11:14:14.737 回答
1

对象上的索引运算符regex_match返回该索引处的匹配子字符串。当索引为 0 时,它返回整个匹配字符串,这就是为什么输出的第一行是{aaa}. (当索引为 1 时,它返回第一个捕获组的内容,即与第一个和对应的正则表达式部分匹配的文本)。在这个例子中,那些是最外面的括号,它再次产生{abc}. 当索引为 2 时,返回第二个捕获组的内容,即第二个(与其对应的 . 之间的文本),从而为您提供aaa.

从您离开的地方再次搜索的最简单方法是使用迭代器:

std::wsregex_iterator it(chatMessage.begin(), chatMessage.end(), e);
for ( ; it != wsregex_iterator(); ++it) {
    std::cout << *it << '\n';
}

(注意:这是一个草图,未经测试)

于 2013-08-05T12:48:22.873 回答