使用std :: regex过滤输入

橡子

我的字符串很丑陋,它由几个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;
}
马丁·尼奥尔(Martin Nyolt)

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]+将匹配es和fs的最长序列因此,上述ab([cd])([ef])目标字符串的第二个子表达式的匹配将匹配ef,而不仅仅是e

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用std :: regex?

来自分类Dev

使用std :: cin中的std :: setw限制输入大小

来自分类Dev

使用RegEx验证用户输入

来自分类Dev

使用JavaScript RegEx验证输入

来自分类Dev

使用输入中的查询进行过滤

来自分类Dev

使用Powershell进行输入验证/数据过滤

来自分类Dev

使用jQuery按输入范围过滤

来自分类Dev

使用输入框过滤KendoGrid

来自分类Dev

Angular JS使用搜索输入过滤数组

来自分类Dev

AngularJS:使用选择和输入过滤记录

来自分类Dev

使用 select 仅过滤部分输入

来自分类Dev

使用 FullCalendar 和输入字段过滤事件

来自分类Dev

使用 __icontains 从输入字段动态过滤

来自分类Dev

使用std :: getline检测输入结束

来自分类Dev

使用std :: array时输入流问题

来自分类Dev

使用std :: ifstream进行输入验证

来自分类Dev

使用std :: cin输入停止while循环

来自分类Dev

如何使用std :: regex匹配多个结果

来自分类Dev

如何使用std :: regex匹配多个结果

来自分类Dev

使用 std::regex 按点解析数字

来自分类Dev

使用RegEx键入时验证用户输入

来自分类Dev

使用Regex输入遮罩文字栏位

来自分类Dev

如何使用选择和输入依据帖子数据过滤结果?

来自分类Dev

使用数据属性和输入来过滤元素?

来自分类Dev

使用输入和DIV搜索过滤器

来自分类Dev

如何使用闪亮输入过滤已编辑的数据表?

来自分类Dev

使用文本输入过滤LI-嵌套LI不显示?

来自分类Dev

使用AngularJS中的单个输入过滤多个字段

来自分类Dev

使用NgModel输入的AngularJS数字格式过滤器指令