我的字符串很丑陋,它由几个URI组成。
:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/0_301_0.svg,:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02011.svg,:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02012.svg,:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02110000.svg
我想做的是去除每次出现的字符:/.,
,因此我可以有一个字符串,该字符串是有效的文件名。
为了做到这一点,我已经写了这个简单的regex表达式:[^(:/,.)]
根据http://www.regexpal.com/,它似乎是正确的regex表达式。
但是,当我运行以下C ++代码时,我没有得到我想要的(只是字母数字字符和下划线),而只是得到了序列中的第一个字母数字字符:S
。
我在使用std :: regex时做错了什么,还是我的regex表达式关闭了?
#include <iostream>
#include <regex>
#include <string>
static const std::string filenames {R"(:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/0_301_0.svg,:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02011.svg,:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02012.svg,:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02110000.svg)"};
static const std::regex filename_extractor("[^(:/,.)]");
int main() {
std::smatch filename_match;
if(std::regex_search(filenames, filename_match, filename_extractor))
{
std::cout << "Number of filenames: " << filename_match.size() << std::endl;
for(std::size_t i = 0; i < filename_match.size(); ++i)
{
std::cout << i << ": " << filename_match[i] << std::endl;
}
}
return 0;
}
的size()
ofstd::smatch
返回子表达式的数量+ 1(带有(
和)
,而您没有)。
您需要std::regex_search
反复呼叫或使用std::regex_iterator
。
另外,您的正则表达式实际上仅搜索单个字符。您需要使用+
来搜索最长的字符序列:[^(:/,.)]+
。
这是您的代码,其中包含来自cppreference.com的示例:
#include <iostream>
#include <iterator>
#include <regex>
#include <string>
static const std::string filenames {R"(:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/0_301_0.svg,:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02011.svg,:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02012.svg,:/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02110000.svg)"};
static const std::regex filename_extractor("[^(:/,.)]+");
int main() {
auto files_begin = std::sregex_iterator(filenames.begin(), filenames.end(), filename_extractor);
for (auto i = files_begin; i != std::sregex_iterator(); ++i) {
std::string filename = i->str();
std::cout << filename << '\n';
}
return 0;
}
但是,这也返回中间的“目录”。如果使用regex [^(:,)]+
,您将得到我希望得到的结果:
/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/0_301_0.svg
/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02011.svg
/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02012.svg
/SymbolStandards/JMSymbology/MIL_STD_2525D_Symbols/02110000.svg
std::regex_search
仅搜索正则表达式的第一个匹配项以及其中的任何子表达式。
例如,表达式ab([cd])([ef])
将匹配字符串xxabcfxxabdef
。第一匹配是部分abcf
,与c
作为匹配的第一子表达[cd]
和e
作为匹配的第二子表达[ef]
。
第二个匹配是该部分abde
(不是abdef
!),其中e
是第二个子表达式的匹配。
使用std::regex_search
,您搜索第一个匹配项,匹配器将为您返回完整的第一个匹配项和子表达式的匹配项。如果要查找其他匹配项,则必须从字符串的其余部分(std::smatch::suffix()
)开始搜索。
另外,正则表达式[ef]
仅匹配单个字符。[ef]+
将匹配e
s和f
s的最长序列。因此,上述ab([cd])([ef])
目标字符串的第二个子表达式的匹配将匹配ef
,而不仅仅是e
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句