本人最近在做一個項目,這個項目里面有一個功能是這樣的,要求這個項目中提供搜索功能,簡單的說,如果里面輸入1-10 11,15,27,39這個字符串,那么你就要從中找到1,2,3,4,5,6,7,8,9,10和11,15,27,39等等這些數字。我考慮了很久,決定使用正則表達式來做,采用的原因有兩點:其一,因為考慮到范圍的問題(比如說位數不能超過三位)這樣的話采用正則表達式比較好處理。其二,考慮到格式的問題,因為如果說寫一個abc-def e,r,t,y,u這種類型的話,我在切割之后還需要進行判斷,這樣很不好處理,因此我考慮了很久,決定采用正則表達式來處理這件事情。
一、設計這部分的思路
二、c++正則表達式的基本用法
2.1 前言
2.2 正則的匹配條件
2.3 c++中正則表達式的三種用法
三、具體的實現步驟
四、總結
考慮到各種情況:
1、1-10 (截取出來的數字1,2,3,4,5,6,7,8,9,10)
2、23,45,57(截取出來的數字為23,45,57)
3、1-10 23,45,57(截取出來的數字1,2,3,4,5,6,7,8,9,10,23,45,57)
4、23,45,57 1-10(截取出來的數字1,2,3,4,5,6,7,8,9,10,23,45,57)
當然,這里要說明一下,目前這個算法有一個部分就是如果只輸入單一數字23那么是沒有辦法處理的,這個需要在代碼上補齊一下這種可能性。
ok,我們開始設計算法了,我的想法是這樣的:因為這是兩部分,所以首先將整個字符串拆分成兩部分,在分別處理,各自解析出相關的數字之后,在將他們統一放到vector的數組中。所以,綜上所述,整個算法可以分成三個部分來進行處理。
1、將字符串拆分成兩部分(第一部分為1-10這部分,第二部分為后面的逗號部分)
2、第二部分解析相應的數字
3、將其存放到一個全局的vector中(之所以使用全局因為后期給其他回調線程用)
二、c++中正則表達式的用法
2.1 前言
首先說一下,本人以前學過正則了,用過shell中grep的正則表達式,c++中的正則表達式和shell中的還是有一定區別的。
不過在匹配條件上確實都差不多。
2.2 正則表達式的條件
正則表達式的條件有很多,如果一個一個記太麻煩了,所以我歸類總結了一下,可以分成三類:
1、關於括號的用法:
():表示分組(這個過會說明怎么用)
{} : 表示匹配的次數(簡單來說{3,5}表示匹配至少3次,至多5次,當然也可以拆開來用)
順便說下,沒有中括號
2、關於內容的匹配
首先我們想到內容匹配一共有三種,分別是數字,字母,空格,所以正則表達式為我們也提供了六種相應的
匹配內容的方法(因為有取反),分別是:
\d:數字
\D:不匹配數字
\w:匹配字母
\W:不匹配字母
\s:匹配空格
\S: 不匹配空格
3、占位符:
這里要說道四種占位符
.:匹配任意單個字符
?:匹配字符0次或者1次
*:匹配字符任意次
+:匹配字符1次到無數次
4、其他字符
^:表示開始匹配
$:表示終止匹配
|:多個條件匹配
2.3 關於c++正則匹配的三種模式
首先說一下,c++正則的用法全部都在regex庫中(這里說一下,因為我用的是c++11的庫,所以到底之前庫能不能用我也不知道),而其中有三種匹配模式,分別為:
regex_match(string,std::regex):匹配全部字符的
regex_search(string,std::regex):匹配部分字符的
regex_replace(string,std::regex, string):用來替換相應字符的
當然這里說一下,無論式match也好,還是search也好,默認匹配第一個字符比如我的字符串是1994 1994 1994 1994,那么他默認只匹配輸出第一個1994。
三、具體的實現步驟
好的,搞清楚了regex的基本用法,我們就可以開始使用他了。首先我們來實現第一步,拆分字符串。以1-10 11,15,27,39為例子,我們可以這樣寫:
匹配1-10的字符串可以這樣寫
bool seperateStr(string str)
{
std::regex pattern("(\\d+)-(\\d+)+"); //這里說明下,第一個和第二個加號表示前面和后面的兩個數字可以無限位,第三個加號考慮到可能出現比如1-10 11-20這種情況,所以這樣設計
smatch result; // 這個可以輸出結果
string::const_iterator iter = str.begin;
string::const_iterator iterEnd = str.end;
string temp;
std::vector<string> vv1;
while(regex_search(iter, iterEnd, result, pattern)) {
temp = result[0];
vv1.push_back(temp);
iter = result[0].second; //這里要說一下,因為之前說了,它是默認匹配第一個的,所以說匹配成功后要把
初始指針向后移動
}
iter = str.begin;
std::vector<string> vv2;
std::regex pattern1 ("((\\d+),(\\d+)+)|(,(\\d+)+)|((\\s\\d+)+)|((\\d+\\\s))"); //針對各種情況設計的匹配條件,這里不做解釋了
while(regex_search(iter, iterEnd,result, pattern1) {
temp = result[0];
vv2.push_back(temp);
iter = result[0].second;
}
}
通過這樣,就可以把里面的內容分開了
OK,搞定了這個問題,我們實現第二部算法,這個式這樣的
bool range(std::vector vv1)
{
// 這里的實現步驟與上面基本一致,只需要把匹配條件稍作修改
std::regex pattern("\\d+");
}
3、最后把解析出的數據放到全局變量vector中,整個部分就完成了。
四、總結
本文主要針對我做的一個小開發對正則表達式進行了理解和說明。