Tokenize a String and Keep Delimiters Using Regular Expression in C++(在C++中使用正则表达式对字符串进行标记化并保留分隔符)
问题描述
我想修改给定的正则表达式以生成以下匹配列表。我很难用语言来描述这个问题。
我想使用正则表达式来匹配一组"令牌"。具体地说,我希望匹配&&
、||
、;
、(
、)
,并且任何不包含这些字符的字符串都应该匹配。
我遇到的问题是区分一个管道和两个管道。我怎样才能得到想要的火柴呢?非常感谢您的帮助!
Link to this example
表达式:
((&{2})|(|{2})|(()|())|(;)|[^&|;()]+)
测试字符串
a < b | c | d > e >> f && ((g) || h) ; i
预期匹配
a < b | c | d > e >> f
&&
(
(
g
)
||
h
)
;
i
实际匹配
a < b
|
c
|
d > e >> f
&&
(
(
g
)
||
h
)
;
i
我正在尝试用C++实现程序的自定义记号赋值程序。
示例代码
std::vector<std::string> Parser::tokenizeInput(std::string s) {
std::vector<std::string> returnTokens;
//tokenize correctly using this regex
std::regex rgx(R"S(((&{2})|(|{2})|(()|())|(;)|[^&|;()]+))S");
std::regex_iterator<std::string::iterator> rit ( s.begin(), s.end(), rgx );
std::regex_iterator<std::string::iterator> rend;
while (rit!=rend) {
std::string tokenStr = rit->str();
if(tokenStr.size() > 0 && tokenStr != " "){
//assure the token is not blank
//and push the token
boost::algorithm::trim(tokenStr);
returnTokens.push_back(tokenStr);
}
++rit;
}
return returnTokens;
}
驱动程序代码示例
//in main
std::vector<std::string> testVec = Parser::tokenizeInput(inputWithNoComments);
std::cout << "input string: " << inputWithNoComments << std::endl;
std::cout << "tokenized string[";
for(unsigned int i = 0; i < testVec.size(); i++){
std::cout << testVec[i];
if ( i + 1 < testVec.size() ) { std::cout << ", "; }
}
std::cout << "]" << std::endl;
产出
input string: (cat file > outFile) || ( ls -l | grep -i )
tokenized string[(, cat file > outFile, ), ||, (, ls -l, grep -i, )]
input string: a && b || c > d >> e < f | g
tokenized string[a, &&, b, ||, c > d >> e < f, g]
input string: foo | bar || foo || bar | foo | bar
tokenized string[foo, bar, ||, foo, ||, bar, foo, bar]
我希望输出是什么
input string: (cat file > outFile) || ( ls -l | grep -i )
tokenized string[(, cat file > outFile, ), ||, (, ls -l | grep -i, )]
input string: a && b || c > d >> e < f | g
tokenized string[a, &&, b, ||, c > d >> e < f | g]
input string: foo | bar || foo || bar | foo | bar
tokenized string[foo | bar, ||, foo, ||, bar | foo | bar]
推荐答案
我建议使用拆分方法,将{-1,0}
传递给sregex_token_iterator
以同时收集未匹配和匹配的子字符串,并使用像&&||||[;()]
这样简单得多的正则表达式,同时丢弃空子字符串(这是由于在找到连续匹配时拆分字符串的方式):
std::regex rx(R"(&&||||[();])");
std::string exp = "a < b | c | d > e >> f && ((g) || h) ; i";
std::sregex_token_iterator srti(exp.begin(), exp.end(), rx, {-1, 0});
std::vector<std::string> tokens;
std::remove_copy_if(srti, std::sregex_token_iterator(),
std::back_inserter(tokens),
[](std::string const &s) { return s.empty(); });
for( auto & p : tokens ) std::cout <<"'"<< p <<"'"<< std::endl;
见C++ demo,输出:
'a < b | c | d > e >> f '
'&&'
' '
'('
'('
'g'
')'
' '
'||'
' h'
')'
' '
';'
' i'
空字符串删除代码的特别奖励授予Jerry Coffin。
这篇关于在C++中使用正则表达式对字符串进行标记化并保留分隔符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在C++中使用正则表达式对字符串进行标记化并保留分隔符
基础教程推荐
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- 设计字符串本地化的最佳方法 2022-01-01
- C++,'if' 表达式中的变量声明 2021-01-01