C++ 0x regex實現關鍵OR敏感字過濾

給出一篇文檔,要求把裏面的「性愛」都替換成「革命」,「性」都替換成「道德」。刪除裏面全部的「A片」。在全部的「蒼井空來了」前面加上「(表相信)」,後面加上「(這是謠言)」。
要求:考慮周密,設想各類會出現的奇怪狀況。由於---咱們是國家安全局!寧肯錯殺一萬,不能漏過一個。
ios

首先考慮到確定要涉及到各類寬字符的過濾故確定要使用unicode來處理,咱們的函數接口不妨設爲
static void filter_unicode(std::wstring& ws_text);
而後題目中的三個需求其實均可以歸納成將子串A替換爲B的操做,故若是沒有特殊要求直接三句boost::replace_all便可搞定。
如今來考慮最後的要求中提到的「奇怪狀況」,那就須要咱們「設身處地」地來思考啦。咱們平時想輸入敏感字時會用到什麼方法呢,無外乎會插入空格或者各類異常標點符號之類,這裏會想到用正則表達式豈不正好?符合咱們需求的相應函數爲std::regex_replace,boost的regex庫也有對應函數,這裏就用c++ 0x原生的了。
咱們的需求是從關鍵字首字符開始匹配,中間若是隻間隔標點符號,且符號結束後的第一個字符與關鍵字尾字符相匹配,則匹配成功,將此串替換爲預設的目標串。要注意到的是c++ 0x和boost中的regex庫並不支持unicode庫定義,好比\p{L} 之類的定義,否則咱們能夠簡單的使用\p{Punct}來完成這個需求了。詳細的符號定義能夠參考http://en.wikipedia.org/wiki/Regular_expression咱們這裏使用到的是\W,能夠排除全部字母(包含中文等)和下劃線,因而正則表達式能夠寫成
性\W*愛
再將下劃線補充上便可完成需求
性[\W|_]*愛

最終完成的代碼以下:
c++

#include <regex> 
#include <locale> 
#include <string> 
#include <iostream> 
 
static wchar_t* rules[][2] = 
{ 
    {L"性(\\W|_)*愛", L"革命"}, 
    {L"性", L"道德"}, 
    {L"A(\\W|_)*片", L""}, 
    {L"蒼(\\W|_)*井(\\W|_)*空(\\W|_)*來(\\W|_)*了", L"(表相信)蒼井空來了(這是謠言)"}, 
}; 
static const int RULE_COUNT = sizeof(rules) / sizeof(rules[0]); 
 
static void filter_unicode(std::wstring& ws_text) 
{ 
    for (int i = 0; i < RULE_COUNT; ++i)
        ws_text = std::regex_replace(ws_text, std::wregex(rules[i][0]), std::wstring(rules[i][1])); 
 
} 
static void test1() 
{ 
    std::locale::global(std::locale("chs")); 
    std::wstring ws_text = L"性不愛性a愛性 \t\r\n`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?·!@#¥%……()——【】{}、,。《》?愛性6A片333蒼井空來了555"; 
    std::wcout << "before:" << ws_text << std::endl; 
 
    filter_unicode(ws_text); 
 
    std::wcout << std::endl << L"---------------------------" << std::endl; 
    std::wcout << "after:" << ws_text << std::endl; 
}

運行結果以下:

相關文章
相關標籤/搜索