:
如果输入包含由, like分隔的严格感兴趣的项目,如item1:item2:item3
问题中的尝试所示,那么您可以使用正则表达式模式
[^:]+
它匹配不是 的连续字符:
,因此是第一个的子字符串:
。这可能也需要捕获([^:]+)
,取决于整体方法。如何使用它来获得所有这些匹配取决于语言。†</sup>
在 C++ 中有不同的方法来解决这个问题。使用std::regex_iterator
#include <string>
#include <vector>
#include <iterator>
#include <regex>
#include <iostream>
int main()
{
std::string str{R"(one:two:three)"};
std::regex r{R"([^:]+)"};
std::vector<std::string> result{};
auto it = std::sregex_iterator(str.begin(), str.end(), r);
auto end = std::sregex_iterator();
for(; it != end; ++it) {
auto match = *it;
result.push_back(match[0].str());
}
std::cout << "Input string: " << str << '\n';
for(auto i : result)
std::cout << i << '\n';
}
按预期打印。
也可以使用std::regex_search,即使它在第一次匹配时返回——通过迭代字符串以在每次匹配后移动搜索开始
#include <string>
#include <regex>
#include <iostream>
int main()
{
std::string str{"one:two:three"};
std::regex r{"[^:]+"};
std::smatch res;
std::string::const_iterator search_beg( str.cbegin() );
while ( regex_search( search_beg, str.cend(), res, r ) )
{
std::cout << res[0] << '\n';
search_beg = res.suffix().first;
}
std::cout << '\n';
}
(有了这个字符串和正则表达式,我们不需要原始字符串文字,所以我在这里删除了它们。)
†</sup>这个问题最初被标记为perl
(没有c ++),也在文本中明确提到它(仍然存在),这个答案的原始版本引用了Perl
/([^:]+)/g
“/g
修饰符”用于“全局”以查找所有匹配项。是//
模式分隔符。
当此表达式绑定 ( =~ ) 到具有目标字符串的变量时,整个表达式在预期列表的上下文中使用时返回匹配列表,因此可以直接将其分配给数组变量。
my @captures = $string =~ /[^:]+/g;
(当按字面意思使用时,()
不需要捕获)
分配给一个数组提供了这个“列表上下文”。如果在“标量上下文”中使用匹配,其中需要单个值,例如在if
测试条件中或分配给标量变量,则返回单个真/假(通常是1
or ''
,空字符串) .