c++11 (MSVS2012) 正则表达式在多行中查找文件名 std::string
c++11 (MSVS2012) regex looking for file names in multiple line std::string
我一直在努力寻找关于这个问题的明确答案,但一直找不到。
所以假设我有字符串(其中 \n 可能是 \r\n - 我想处理两者 - 不确定这是否相关)
"4345t435\ng54t a_file_123.xml rk\ngreg a_file_j34.xml fger 43t54"
然后我想要匹配:
- a_file_123.xml
- a_file_j34.xml
这是我的测试代码:
const str::string s = "4345t435\ng54t a_file_123.xml rk\ngreg a_file_j34.xml fger 43t54";
std::smatch matches;
if (std::regex_search(s, matches, std::regex("a_file_(.*)\.xml")))
{
std::cout << "total: " << matches.size() << std::endl;
for (unsigned int i = 0; i < matches.size(); i++)
{
std::cout << "match: " << matches[i] << std::endl;
}
}
输出为:
total: 2
match: a_file_123.xml
match: 123
我不太明白为什么匹配 2 只是“123”...
您只有一场比赛,而不是两场比赛,因为 regex_search
方法 return 是一场比赛。您打印的是两个 group 值,第 0 组(整个匹配项,此处为 a_file_123.xml
)和第 1 组(捕获组值,此处为 123
一个子字符串 captured,其中包含您在模式中定义为 (.*)
的捕获组)。
如果你想匹配多个字符串,你需要使用正则表达式迭代器,而不是只 return 第一个匹配的 regex_search
。
此外,.*
过于贪婪,如果在同一行上有超过 1 个匹配项,将会 return 奇怪的结果。看来你要匹配字母或数字,所以 .*
可以用 \w+
代替。嗯,如果真有什么,就用.*?
.
使用
const std::string s = "4345t435\ng54t a_file_123.xml rk\ngreg a_file_j34.xml fger 43t54";
const std::regex rx("a_file_\w+\.xml");
std::vector<std::string> results(std::sregex_token_iterator(s.begin(), s.end(), rx),
std::sregex_token_iterator());
std::cout << "Number of matches: " << results.size() << std::endl;
for (auto result : results)
{
std::cout << result << std::endl;
}
看到 C++ demo 屈服
Number of matches: 2
a_file_123.xml
a_file_j34.xml
关于正则表达式的注释
a_file_
- 文字子串
\w+
- 1+ 个单词字符(字母、数字、_
)(请注意,如果您想匹配任何字符,可以在此处使用 [^.]*?
而不是 \w+
char,0 次或多次重复,尽可能少,直到第一个 .xml
)
\.
- 一个点(如果你不转义它,它将匹配除换行字符之外的任何字符)
xml
- 文字子串。
我一直在努力寻找关于这个问题的明确答案,但一直找不到。
所以假设我有字符串(其中 \n 可能是 \r\n - 我想处理两者 - 不确定这是否相关)
"4345t435\ng54t a_file_123.xml rk\ngreg a_file_j34.xml fger 43t54"
然后我想要匹配:
- a_file_123.xml
- a_file_j34.xml
这是我的测试代码:
const str::string s = "4345t435\ng54t a_file_123.xml rk\ngreg a_file_j34.xml fger 43t54";
std::smatch matches;
if (std::regex_search(s, matches, std::regex("a_file_(.*)\.xml")))
{
std::cout << "total: " << matches.size() << std::endl;
for (unsigned int i = 0; i < matches.size(); i++)
{
std::cout << "match: " << matches[i] << std::endl;
}
}
输出为:
total: 2
match: a_file_123.xml
match: 123
我不太明白为什么匹配 2 只是“123”...
您只有一场比赛,而不是两场比赛,因为 regex_search
方法 return 是一场比赛。您打印的是两个 group 值,第 0 组(整个匹配项,此处为 a_file_123.xml
)和第 1 组(捕获组值,此处为 123
一个子字符串 captured,其中包含您在模式中定义为 (.*)
的捕获组)。
如果你想匹配多个字符串,你需要使用正则表达式迭代器,而不是只 return 第一个匹配的 regex_search
。
此外,.*
过于贪婪,如果在同一行上有超过 1 个匹配项,将会 return 奇怪的结果。看来你要匹配字母或数字,所以 .*
可以用 \w+
代替。嗯,如果真有什么,就用.*?
.
使用
const std::string s = "4345t435\ng54t a_file_123.xml rk\ngreg a_file_j34.xml fger 43t54";
const std::regex rx("a_file_\w+\.xml");
std::vector<std::string> results(std::sregex_token_iterator(s.begin(), s.end(), rx),
std::sregex_token_iterator());
std::cout << "Number of matches: " << results.size() << std::endl;
for (auto result : results)
{
std::cout << result << std::endl;
}
看到 C++ demo 屈服
Number of matches: 2
a_file_123.xml
a_file_j34.xml
关于正则表达式的注释
a_file_
- 文字子串\w+
- 1+ 个单词字符(字母、数字、_
)(请注意,如果您想匹配任何字符,可以在此处使用[^.]*?
而不是\w+
char,0 次或多次重复,尽可能少,直到第一个.xml
)\.
- 一个点(如果你不转义它,它将匹配除换行字符之外的任何字符)xml
- 文字子串。