如何使用regex_replace()

时间:2019-08-25 11:07:32

标签: c++

当某些特殊字符(例如,',“,\ 、?)出现在字符串中时,我需要在它们之前插入反斜杠。

我不想使用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

2 个答案:

答案 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)"将以某种方式帮助您解决无法理解的转义符狂欢。