gpt4 book ai didi

c++ - 正则表达式中的转义 (\') 单引号在两个单引号之间采用字符串。

转载 作者:太空宇宙 更新时间:2023-11-04 12:58:48 24 4
gpt4 key购买 nike

我有以下字符串:

std::string s("server ('m1.labs.teradata.com') username ('use\\')r_*5') password('u\" er 5') dbname ('default')");

我使用了以下代码:

int main() {
std::regex re(R"('[^'\\]*(?:\\[\s\S][^'\\]*)*')");
std::string s("server ('m1.labs.teradata.com') username ('use\\')r_*5') password('u\" er 5') dbname ('default')");
unsigned count = 0;
for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), re);
i != std::sregex_iterator();
++i)
{
std::smatch m = *i;
cout << "the token is"<<" "<< m.str() << endl;
count++;
}
cout << "There were " << count << " tokens found." << endl;
return 0;

以上字符串的输出是:

the token is   'm1.labs.teradata.com'
the token is 'use\')r_*5'
the token is 'u" er 5'
the token is 'default'
There were 4 tokens found.

现在如果上面代码中提到的字符串s是

std::string s("server ('m1.labs.ter\'adata.com') username ('use\\')r_*5') password('u\" er 5') dbname ('default')");

输出变为:

the token is   'm1.labs.ter'
the token is ') username ('
the token is ')r_*5'
the token is 'u" er 5'
the token is 'default'
There were 5 tokens found.

现在两个字符串的输出不同:预期的输出是“提取括号和单引号之间的所有内容,即

the token is   'm1.labs.teradata.com'
the token is 'use\')r_*5'
the token is 'u" er 5'
the token is 'default'
There were 4 tokens found

我在代码中提到的正则表达式能够正确提取但无法转义“单引号”。它能够转义 ",) 等但不能转义单引号。可以修改正则表达式以产生我需要的输出吗?提前致谢。

最佳答案

您使用的是我昨天通过评论分享的正确正则表达式。它匹配可能在内部转义了单引号的单引号字符串文字。

std::regex re(R"('([^'\\]*(?:\\[\s\S][^'\\]*)*)')");
std::string s("server ('m1.labs.teradata.com') username ('u\\'se)r_*5') password('uer 5') dbname ('default')");
unsigned count = 0;
for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), re);
i != std::sregex_iterator();
++i)
{
std::smatch m = *i;
cout << "the token is"<<" "<< m.str(1) << endl;
count++;
}
cout << "There were " << count << " tokens found." << endl;

这里是 my C++ demo

请注意,文字字符串 ('u\'se)r_*5') 应该像这样使用常规字符串文字定义,其中支持转义序列 where文字反斜杠应使用 \\:

定义
"('u\\'se)r_*5')"

或使用原始字符串文字,其中反斜杠表示文字反斜杠:

R"(('u\'se)r_*5'))"

R"(...)" 形成原始字符串文字。

图案细节:

  • ' - 单引号
  • [^'\\]* - 除了单引号和反斜杠之外的 0+ 个字符
  • (?:\\[\s\S][^'\\]*)* - 零个或多个序列:
    • \\[\s\S] - 任何反斜杠转义字符
    • [^'\\]* - 除了 '\
    • 之外的 0+ 个字符
  • ' - 单引号。

请注意,为了避免将第一个单引号匹配为转义引号,您需要调整表达式,如 this snippet :

std::regex re(R"((?:^|[^\\])(?:\\{2})*'([^'\\]*(?:\\[\s\S][^'\\]*)*)')");
std::string s("server ('m1.labs.teradata.com') username ('u\\'se)r_*5') password('uer 5') dbname ('default')");
unsigned count = 0;
for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), re);
i != std::sregex_iterator();
++i)
{
std::smatch m = *i;
cout << "the token is"<<" "<< m.str(1) << endl;
count++;
}
cout << "There were " << count << " tokens found." << endl;

(?:^|[^\\])(?:\\{2})* 前缀将匹配字符串的开头或除 \ 之外的任何字符> 然后是 2 个 \ 的 0+ 序列,因此首先不会抓取任何转义的 '

最后,如果您只需要将匹配列表放入 vector 中,您可以使用

#include <iostream>
#include <string>
#include <vector>
#include <regex>

using namespace std;

int main() {
std::regex rx("'[^']*(?:''[^']*)*'");
std::string sentence("server ('m1.labs.\\''tera\"da ta.com') username ('us *(er'')5') password('uer 5') dbname ('default')");
std::vector<std::string> names(std::sregex_token_iterator(sentence.begin(), sentence.end(), rx),
std::sregex_token_iterator());

for( auto & p : names ) cout << p << endl;
return 0;
}

参见 C++ demo .

关于c++ - 正则表达式中的转义 (\') 单引号在两个单引号之间采用字符串。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45207532/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com