Regular Expression
正規表示式
Regular Expression……?
電腦比對字串是否符合規定
e.g.


regex使用環境
- C++ 11
#include <regex>
- 宣告正規表示式
- 常用符號
#include <regex>
int main(){
std::regex 名稱("格式填入");
return 0;
}字元類
| 舉例 | 其他表示方式 | 說明 |
|---|---|---|
| \w | [_[:alnum:]], [A-Za-z0-9_] |
數字、字母、底線 |
| \W | [^_[:alnum:]], [^A-Za-z0-9_] |
非數字、字母、底線 |
| \d | [[:digit:]], [0-9] |
數字 |
| \D | [^[:digit:]], [^0-9] |
非數字 |
| \s | [[:space:]] | 空白字元(包含\n, \t, \r, \f) |
| \S | [^[:space:]] | 非空白字元 |
特殊字元
| 舉例 | 說明 |
|---|---|
| . | 任何字元 |
| [ ] | 含括字元類 |
| { } | 含括重複次數 |
| ^ | 否定;以…開始 |
| $ | 以…結束 |
出現次數
| 舉例 | 說明 |
|---|---|
| {n} | 出現n次 |
| {n,} | 出現n次以上 |
| {n,m} | 出現n到m次 |
| 特殊重複字元 | 等效表示法 |
|---|---|
| * | {0,} |
| + | {1,} |
| ? | {0,1} |
What can regular expression do?
- 匹配 regex_match
- 搜尋 regex_search
- 替換 regex_replace
regex_match(字串, 正規表示式)
#include <iostream>
#include <regex>
using namespace std;
int main(){
string s1 = "!@#$"; // 宣告一個沒有字母、數字、底線的字串
string s2 = "12ab_"; // 宣告一個有字母、數字、底線的字串
regex ex("\\w*"); // 宣告正規表示式
cout << s1 << " is all _[:alnum:]: " << regex_match(s1, ex) << endl; // 符合輸出1
cout << s2 << " is all _[:alnum:]: " << regex_match(s2, ex) << endl; // 不符合輸出0
return 0;
}匹配字串是否符合格式
regex_search(字串, 儲存結果, 正規表示式)
#include <iostream>
#include <regex>
using namespace std;
int main(){
string s = "ab123cdef"; // 字串
regex ex("\\d+"); // 正規表示式
smatch match; // 儲存結果容器
regex_search(s, match, ex); // 執行搜尋函式
cout << s << " contains digit: " << match[0] << endl; // 輸出結果
return 0;
}
搜尋符合格式的字串
搜尋字串:smatch
搜尋字元陣列:cmatch
regex_replace(字串, 正規表示式, 替代字串)
#include <iostream>
#include <regex>
using namespace std;
int main(){
string s = "ab123cdef"; // 字串
regex ex("\\d+"); // 正規表示式
cout << regex_replace(s, ex, "xxx") << endl; // 輸出替換數字的結果
return 0;
}修改符合格式的字串
Practice
小資要統整大家的出生年月日。為了使資料整齊,他想規定大家以xxxx-xx-xx的方式(e.g. 2000-01-01)。
請幫小資寫一個程式。若輸入符合格式,則輸出「Thank you.」;不符合格式,則輸出「Please follow the format.」
寫好程式後,請自行輸入三筆測試資料,並截圖執行的結果放到fb。
| 輸入 | 輸出 |
|---|---|
| 2004-10-26 | Thank you. |
| 2005/04/25 | Please follow the format. |
| 2005-7-19 | Please follow the format. |
Reference Answer
#include <iostream>
#include <regex>
#include <string>
int main(){
std::string ipt;
std::cin >> ipt;
std::regex form("\\d{4}-\\d{2}-\\d{2}");
if(std::regex_match(ipt, form)){
std::cout << "Thank you.";
}else{
std::cout << "Please follow the format.";
}
return 0;
}補充:iterator and regular expression
正規表示式的迭代器
A regular expression, regex or regexp ((sometimes called a rational expression)) is a sequence of characters that define a search pattern. Usually such patterns are used by string searching algorithms for “find” or “find and replace” operations on strings, or for input validation. It is a technique developed in theoretical computer science and formal language theory.
這裡有一篇文章(請不要在意它到底寫了什麼٩(●˙▿˙●)۶…⋆ฺ),
想要統計字數的話,可以怎麼做呢?
我們可以先思考:
1. 單字由字母組成,所以正規表示式應該選用[^\\s]
2. 一個單字會有一個以上的字母,所以應該用+
總結:正規表示式應該為"[^\\s]+"
程式講解
#include <regex>
#include <iterator> //引入迭代器
#include <iostream>
#include <string>
int main() {
std::regex word_regex("[^\\s]+"); //剛剛討論過的正規表示式
std::string line;
getline(std::cin, line); //輸入含有空白的字串
auto iter_begin = std::sregex_iterator(line.begin(), line.end(), word_regex);//通過正規表示式迭代器從文字行的逐一匹配
auto iter_end = std::sregex_iterator();
std::cout << "It contains " << std::distance(iter_begin, iter_end) << " words"; //輸出字數
return 0;
}附錄:other character classification
其它字元類
| 字元類 | 說明 |
|---|---|
| [[:alpha:]] | 任意字母 |
| [[:blank:]] | 非換行的空白字元 |
| [[:cntrl:]] | 控制字元 |
| [[:graph:]] | 圖形字元 |
| [[:lower:]] | 小寫字母 |
| [[:print:]] | 可列印字元 |
| [[:punct:]] | 標點符號 |
| [[:upper:]] | 大寫字母 |
| [[:xdigit:]] | 十六進位制的數字字元 |
deck
By alice11135917
deck
- 147