我有以下代码:
#include <iostream>
#include <regex>
using namespace std;
int main()
{
string s;
s = "server ('m1.labs.terad ata.com') username ('us er5') password('user)5') dbname ('def\\ault')";
regex re("(\'(.*?)\'\)");
sregex_token_iterator i(s.begin(), s.end(), re, 1);
sregex_token_iterator j;
unsigned count = 0;
while(i != j)
{
cout <<*i<< endl;
count++;
i++;
}
cout << "There were " << count << " tokens found." << endl;
return 0;
}
上面的正则表达式旨在提取单引号之间的所有内容。
但是如何制作正则表达式以便它能够提取转义的单引号(示例用户名(user''5)应该被提取为'user'5'。
提前致谢。我真的需要帮助。已经尝试了这么多天。
示例
'm1.labs.terad ata.com'
'us er5'
'user)5'
'def\ault'
找到了4个令牌。请注意,字符串周围的单引号应该在那里。在此先感谢您的帮助。
但现在我的字符串是
s = "server ('m1.labs.terad ata.com') username ('us ''er5') password('user)5') dbname ('def\\ault')";
输出应为:
'm1.labs.terad ata.com'
'us 'er5' <<<<<<<<<<<<<<<<<<<
'user)5'
'def\ault'
答案 0 :(得分:2)
但是如何制作正则表达式以便它能够提取转义的单引号(示例用户名(用户&#39;&#39; 5)应该被提取为&#39; user&#39; 5&#39;
唉。是you meant那是什么?我was right关于X / Y问题。
注意:您描述的内容称为转义特殊字符。两种常见的逃避特殊字符的方法:
- 重复此操作(例如
printf("100%%");
以打印100%
)- 醇>
使用另一个转义(通常是反斜杠)引入它。例如。
std::cout << "Hello \"World\"" << std::endl;
或者,还有一个复杂的例子:
std::cout << "Newline is \\n" << std::endl;
在这里:只需添加q >> char_(q)
即可接受重复报价作为quote-escape:
auto quoted = [](char q) {
return lexeme[ q >> *(
q >> char_(q) // accept repeated quotes as quote-escape
| '\\' >> char_ // accept backs-slash escape
| char_ - q // accept any other non-quote
) >> q]; };
相对于tokenizing string , accepting everything between given set of characters in CPP
,没有其他任何变化<强> Live On Coliru 强>
#include <iostream>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <map>
using Config = std::map<std::string, std::string>;
using Entry = std::pair<std::string, std::string>;
namespace parser {
using namespace boost::spirit::x3;
template <typename T> auto as = [](auto p) { return rule<struct _, T> {} = p; };
auto quoted = [](char q) { return lexeme[q >> *(q >> char_(q) | '\\' >> char_ | char_ - q) >> q]; };
auto value = quoted('\'') | quoted('"');
auto key = lexeme[+alpha];
auto pair = key >> '(' >> value >> ')';
auto config = skip(space) [ *as<Entry>(pair) ];
}
Config parse_config(std::string const& cfg) {
Config parsed;
auto f = cfg.begin(), l = cfg.end();
if (!parse(f, l, parser::config, parsed))
throw std::invalid_argument("Parse failed at " + std::string(f,l));
return parsed;
}
int main() {
auto const text = "server ('m1.labs.teradata.com') username ('use'')r_*5') password('u\" er 5') dbname ('default')";
Config cfg = parse_config(text);
for (auto& setting : cfg)
std::cout << "Key " << setting.first << " has value " << setting.second << "\n";
}
打印
Key dbname has value default
Key password has value u" er 5
Key server has value m1.labs.teradata.com
Key username has value use')r_*5
答案 1 :(得分:0)
您应该查看look-around和conditional正则表达式。
并且正则表达式引擎应该 PCRE 兼容。 (我不知道C ++)
你应该更新使用正则表达式,如果你不理解它,你已经在互联网上找到了。
尝试'((?:[^']|'')*?)'(?!')
(demo on 101regex)