正則表達式:文本處理的瑞士軍刀
正則表達式(Regular Expression,簡稱 Regex)是一種用于匹配、查找和操作文本的強大工具。它通過定義一種特殊的字符串模式,可以快速地在文本中搜索、替換或提取符合特定規則的內容。正則表達式廣泛應用于編程、文本編輯、數據處理等領域,是每個開發者必備的技能之一。
一、正則表達式的核心概念
1. 模式(Pattern)
正則表達式的核心是一個模式字符串,它定義了需要匹配的文本規則。例如:
\d
匹配任意數字(0-9)[a-z]
匹配任意小寫字母.*
匹配任意字符(除換行符外)
2. 匹配(Match)
在目標文本中查找符合模式的內容。例如:
- 正則表達式
\d{3}
可以匹配文本中的任意連續3個數字(如 “123”)。
3. 捕獲組(Capture Group)
用括號 ()
將部分模式括起來,可以提取匹配的子內容。例如:
- 正則表達式
(\d{4})-(\d{2})-(\d{2})
可以匹配日期格式 “2023-10-05”,并分別捕獲年、月、日。
二、正則表達式的語法規則
1. 基本元字符
元字符 | 描述 | 示例 |
---|---|---|
. | 匹配任意單個字符(除換行符外) | a.c 匹配 “abc” |
\d | 匹配任意數字(0-9) | \d{3} 匹配 “123” |
\w | 匹配字母、數字或下劃線 | \w+ 匹配 “hello_123” |
\s | 匹配空白字符(空格、制表符等) | \s+ 匹配 " " |
2. 量詞
量詞 | 描述 | 示例 |
---|---|---|
* | 匹配前一個元素0次或多次 | a* 匹配 “”、“a”、“aa” |
+ | 匹配前一個元素1次或多次 | \d+ 匹配 “1”、“123” |
? | 匹配前一個元素0次或1次 | a? 匹配 “”、“a” |
{n} | 匹配前一個元素恰好n次 | \d{3} 匹配 “123” |
{n,m} | 匹配前一個元素至少n次,至多m次 | \d{2,4} 匹配 “12”、“1234” |
3. 字符類
語法 | 描述 | 示例 |
---|---|---|
[abc] | 匹配括號內的任意一個字符 | [aeiou] 匹配 “a”、“e” |
[^abc] | 匹配不在括號內的任意字符 | [^0-9] 匹配 “a”、“!” |
[a-z] | 匹配范圍內的任意字符 | [A-Za-z] 匹配大寫或小寫字母 |
4. 邊界匹配
語法 | 描述 | 示例 |
---|---|---|
^ | 匹配字符串的開頭 | ^Hello 匹配 “Hello world” 的開頭 |
$ | 匹配字符串的結尾 | world$ 匹配 “Hello world” 的結尾 |
\b | 匹配單詞邊界 | \bcat\b 匹配 “cat” 但不匹配 “category” |
三、正則表達式的應用場景
1. 數據驗證
- 驗證郵箱格式:
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
- 驗證手機號格式:
^1[3-9]\d{9}$
2. 文本搜索與替換
- 查找所有日期:
\d{4}-\d{2}-\d{2}
- 替換HTML標簽:
<[^>]+>
3. 數據提取
- 提取URL中的域名:
https?://([^/\s]+)
- 提取文本中的所有數字:
\d+
四、正則表達式的編程實現(C++示例)
C++11 引入了 <regex>
庫,支持正則表達式操作。以下是一個簡單的示例:
#include <iostream>
#include <regex>
#include <string>int main() {std::string text = "Contact us at support@example.com or sales@domain.com.";std::regex emailPattern(R"(\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b)");auto words_begin = std::sregex_iterator(text.begin(), text.end(), emailPattern);auto words_end = std::sregex_iterator();std::cout << "Found emails:\n";for (std::sregex_iterator i = words_begin; i != words_end; ++i) {std::smatch match = *i;std::cout << match.str() << '\n';}return 0;
}
輸出:
Found emails:
support@example.com
sales@domain.com
五、正則表達式的性能優化
1. 避免貪婪匹配
- 貪婪匹配(默認):
匹配整個<.*>
<div>content</div>
。 - 非貪婪匹配:
匹配<.*?>
<div>
和</div>
兩個標簽。
2. 預編譯正則表達式
在多次使用同一正則表達式時,預編譯可以顯著提高性能:
std::regex emailPattern(R"(\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b)");
3. 使用非捕獲組
如果不需要捕獲組的內容,使用 (?:...)
可以提高性能:
(?:\d{4})-(?:\d{2})-(?:\d{2})
六、正則表達式的學習資源
-
在線測試工具:
- Regex101
- RegExr
-
經典書籍:
- 《精通正則表達式》(Jeffrey E.F. Friedl)
- 《正則表達式必知必會》
-
練習平臺:
- LeetCode 正則表達式題目
- HackerRank Regex Challenges
正則表達式是文本處理的利器,但也需要謹慎使用。掌握其核心語法和優化技巧,可以讓你在數據處理中事半功倍!