[英]How to use 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;
}
輸入:測試\\“輸入”?
輸出:testing \\\\\\“ input \\” \\?
錯誤消息:在拋出“ std :: regex_error” what()實例后終止調用:regex_error
當某些特殊字符(如“',”,\\ 、?)出現在字符串中時,我需要在其之前插入反斜杠。
確定,所以regex_replace
函數一定會為您完成此操作。 在這種情況下要注意的陷阱是字面轉義和特殊字符的解釋。
這里的第一級是C ++中字符串文字的特殊字符。 這主要涉及雙引號字符以開始和結束字符串文字,反斜杠字符用於轉義特殊字符或編碼非字母數字字符。
第二級是就正則表達式引擎而言的特殊字符,它具有自己的正則表達式語法 。 這比語言中的字符串文字更復雜。
因此,如果要為常規字符串文字編碼特殊字符,則需要將其轉義一次。 如果要編碼特殊字符以將其從字面上傳遞給regex編譯器,則需要對其進行兩次轉義。
例如,如果您鍵入:
"abc\n"
那么反斜杠-n將被解釋為換行符,因此給出字節序列(包括空終止):
{ 0x61, 0x62, 0x63, 0x0a, 0x00 }
因此,如果希望反斜杠按字面意義進行解釋,則必須對其進行轉義,因此:
"abc\\n"
結果是:
{ 0x61, 0x62, 0x63, 0x5c, 0x6e, 0x00 }
如果只想打印此字符串,則將獲得預期的結果。 但是,如果將此字符串傳遞給regex引擎,它將看到第四個字節是反斜杠,並對其進行特殊處理,以轉義或解釋以下字符。 如果這無效,則會引發異常-這就是您所看到的。
在處理正則表達式時,我認為使用原始字符串會更容易。 這是寫文字字符串的一種特殊方式,因此編譯器不解釋字符串內容。 這意味着您可以直接將字符串傳遞給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\\
這可以通過非常簡單的方法來完成。 您需要查找有關正則表達式的更多文檔。 如果沒有特殊標志,它將使用std :: ECMAScript語法 。
您可以將所有搜索字符放在字符類中。 因此放在[]中。 例:
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)"
將以某種方式幫助您解決無法R"(some_raw_string)"
轉義符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.