首页 > 解决方案 > 如何使用 regex_replace()

问题描述

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

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

输入:测试\“输入”?

输出:测试\\\\“输入\\”\\?

错误消息:在抛出 'std::regex_error' 实例后调用终止 what(): regex_error

标签: c++

解决方案


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

好的,所以该regex_replace功能肯定会为您做到这一点。在这种情况下要注意的陷阱是文字转义和特殊字符的解释。

这里的第一级是 C++ 中用于字符串文字的特殊字符。这主要涉及用于开始和结束字符串文字的双引号字符,以及用于转义特殊字符或编码非字母数字字符的反斜杠字符。

第二层是正则表达式引擎所关心的特殊字符,它有自己的正则表达式语法。这比语言中的字符串文字更复杂。

因此,如果您想为常规字符串文字编码特殊字符,则需要将其转义一次。如果要对特殊字符进行编码以将其按字面意思传递给正则表达式编译器,则需要对其进行两次转义。

例如,如果您键入:

"abc\n"

那么反斜杠-n 将被解释为换行符,因此给出字节序列(包括空终止):

{ 0x61, 0x62, 0x63, 0x0a, 0x00 }

因此,如果您希望按字面解释反斜杠,则必须对其进行转义,因此:

"abc\\n"

这导致:

{ 0x61, 0x62, 0x63, 0x5c, 0x6e, 0x00 }

如果你只想打印这个字符串,你会得到预期的结果。但是如果你将此字符串传递给正则表达式引擎,它会看到第四个字节是反斜杠并对其进行特殊处理,转义或解释以下字符。如果这无效,则会引发异常 - 这就是您所看到的。

在处理正则表达式时,我认为使用原始字符串更容易。这是一种可以编写文字字符串的特殊方式,因此编译器不会解释字符串内容。这意味着您可以直接将字符串传递给正则表达式引擎,并且基本上可以跳到第二级。

这是 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\\

推荐阅读