当某些特殊字符(例如,',“,\ 、?)出现在字符串中时,我需要在它们之前插入反斜杠。
我不想使用boost或任何其他字符串函数。最好是c ++的算法。
#include <stdio.h>
#include <regex>
#include <bits/stdc++.h>
int main(){
std::string str;
std::cout <<"Enter the string : ";
std::getline(std::cin, str);
str=std::regex_replace(str, std::regex("\\"), "\\\\");
str=std::regex_replace(str, std::regex("\'"), "\\\'");
str=std::regex_replace(str, std::regex("\?"), "\\\?");
str=std::regex_replace(str, std::regex("\""), "\\\"");
std::cout<< str<<std::endl;
}
输入:正在测试\“输入”?
output:testing \\\“ input \” \?
错误消息: 抛出'std :: regex_error'实例后终止调用 what():regex_error
答案 0 :(得分:0)
当某些特殊字符(例如,',“,\ 、?)出现在字符串中时,我需要在它们之前插入反斜杠。
确定,因此regex_replace
函数一定会为您完成此操作。在这种情况下,要注意的陷阱是文字转义和特殊字符的解释。
这里的第一级是C ++中字符串文字的特殊字符。这主要涉及双引号字符,以开始和结束字符串文字,反斜杠字符用于转义特殊字符或编码非字母数字字符。
第二级是就正则表达式引擎而言的特殊字符,它具有自己的regular expression grammar。这比该语言中的字符串文字更复杂。
因此,如果要为常规字符串文字编码特殊字符,则需要将其转义一次。如果要编码特殊字符以将其从字面上传递给regex编译器,则需要两次对其进行转义。
例如,如果您输入:
"abc\n"
然后,反斜杠-n将被解释为换行符,因此给出字节序列(包括空终止):
{ 0x61, 0x62, 0x63, 0x0a, 0x00 }
因此,如果您希望反斜杠按字面意义进行解释,则必须将其转义,因此:
"abc\\n"
结果为:
{ 0x61, 0x62, 0x63, 0x5c, 0x6e, 0x00 }
如果只想打印此字符串,则将获得预期的结果。但是,如果将此字符串传递给regex引擎,它将看到第四个字节是反斜杠,并对其进行特殊处理,以转义或解释以下字符。如果这无效,则会引发异常-这就是您所看到的。
在处理正则表达式时,我认为使用raw strings会更容易。这是写文字字符串的一种特殊方式,因此编译器不解释字符串内容。这意味着您可以直接将字符串传递给regex引擎,并从本质上跳到第二级。
这是C ++ 11的一项新功能,您可以在字符串的开头加上大写的R,然后在字符串竞赛中加上括号和可选的定界符字符串(只需是唯一的)即可。
我已经使用原始字符串对程序进行了调整,使其以您描述的方式工作:
//
// Build with minimum C++ language level of C++11, eg:
//
// c++ --std=c++11 -o ans ans.cpp
#include <iostream>
#include <regex>
int main (int argc, char* argv[])
{
std::string str;
std::cout << "Enter the string : ";
std::getline(std::cin, str);
str = std::regex_replace(str, std::regex(R"(\\)"), R"(\\)");
str = std::regex_replace(str, std::regex(R"(')"), R"(\')");
str = std::regex_replace(str, std::regex(R"(\?)"), R"(\?)");
str = std::regex_replace(str, std::regex(R"(\")"), R"(\")");
std::cout << str << std::endl;
return 0;
}
这是一个示例练习,练习所有符号:
Enter the string : one 'two' ?three? "four" \five\
one \'two\' \?three\? \"four\" \\five\\
答案 1 :(得分:0)
这可以通过非常简单的方法来完成。您需要查找有关正则表达式的更多文档。如果没有特殊标志,它将使用std::ECMAScript syntax。
您可以将所有搜索字符放在字符类中。因此放在[]中。示例:
R"(['"\?])"
然后,对于替换字符串,您需要阅读有关std::regex_replace的信息。在“ fmt”字符串中,可以使用特殊字符进行反向引用。
例如,“ $&”将为您提供完整匹配的副本。
您的程序将与
一样简单#include <iostream>
#include <regex>
int main()
{
std::string text{R"(one 'two' ?three? "four" \five\)"};
std::cout << std::regex_replace(text, std::regex(R"(['"\?])"), R"(\$&)") << "\n";
return 0;
}
原始字符串R"(some_raw_string)"
将以某种方式帮助您解决无法理解的转义符狂欢。