# Linux的正則表達式實例分析
## 1. 正則表達式概述
### 1.1 什么是正則表達式
正則表達式(Regular Expression,簡稱regex)是一種用于描述字符串匹配模式的特殊語法。它由普通字符(如字母a-z)和特殊字符(稱為"元字符")組成,形成一套簡潔而強大的文本處理工具。
在Linux系統中,正則表達式被廣泛應用于:
- 文本搜索(grep)
- 文本替換(sed)
- 文件查找(find)
- 文本處理(awk)
- 編程語言(Perl, Python等)
### 1.2 基本正則表達式(BRE)與擴展正則表達式(ERE)
Linux中有兩種主要的正則表達式風格:
| 特性 | 基本正則表達式(BRE) | 擴展正則表達式(ERE) |
|---------------------|-------------------|-------------------|
| 元字符需要轉義 | 是 | 否 |
| 使用命令 | grep, sed默認 | grep -E, egrep |
| 量詞表示 | \\{ \\} | { } |
| 邏輯或 | \\| | | |
## 2. 正則表達式基礎語法
### 2.1 字符匹配
#### 單個字符匹配
- `.` 匹配任意單個字符(除換行符)
- `[abc]` 匹配a、b或c中的任意一個字符
- `[^abc]` 匹配除a、b、c外的任意字符
- `[a-z]` 匹配a到z范圍內的任意小寫字母
示例:
```bash
# 查找包含"cat"或"cot"的行
grep "c[ao]t" file.txt
# 查找不以字母開頭的行
grep "^[^a-zA-Z]" file.txt
\d
數字,等價于0-9\w
單詞字符,等價于[A-Za-z0-9_]\s
空白字符(空格、制表符等)^
行首錨定$
行尾錨定\<
單詞開頭\>
單詞結尾示例:
# 查找以"Linux"開頭的行
grep "^Linux" file.txt
# 查找以"end"結尾的完整單詞
grep "\<end\>" file.txt
*
前導字符出現0次或多次+
前導字符出現1次或多次(ERE)?
前導字符出現0次或1次(ERE){n}
前導字符恰好出現n次{n,}
前導字符至少出現n次{n,m}
前導字符出現n到m次示例:
# 查找包含2到4個連續數字的行
grep -E "[0-9]{2,4}" file.txt
# 查找類似"color"或"colour"的單詞
grep "colou?r" file.txt
( )
定義子表達式并捕獲匹配內容(?: )
僅分組不捕獲(ERE)\n
引用第n個捕獲組示例:
# 查找重復單詞
grep -E "\<([A-Za-z]+) +\1\>" file.txt
# 交換前兩個字段
sed -E 's/([^ ]+) +([^ ]+)/\2 \1/' file.txt
(?=pattern)
正向預查(?!pattern)
負向預查(?<=pattern)
正向回顧(?<!pattern)
負向回顧示例:
# 查找后面跟著"ing"的"run"
grep -P "run(?=ing)" file.txt
# 查找不在引號內的數字
grep -P '(?<!")\d+(?!")' file.txt
# 提取訪問量前10的IP地址
grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' access.log | sort | uniq -c | sort -nr | head -10
# 查找404錯誤請求
grep -E ' 404 [0-9]+ ' access.log
# 提取2023年10月10日10點到11點的日志
grep -E '10/Oct/2023:10:[0-5][0-9]:' access.log
# 查找大于100MB的日志文件
find /var/log -type f -size +100M -regex '.*\.log$'
# 檢查/etc/passwd格式是否正確
grep -Ev '^[^:]+:[x*]:[0-9]+:[0-9]+:[^:]*:[^:]+:[^:]+$' /etc/passwd
# 提取第二列包含電子郵件的行
grep -E '^[^,]*,[^,]*@[^,]+\.[^,]+,' data.csv
# 將日期格式從MM/DD/YYYY改為YYYY-MM-DD
sed -E 's#([0-9]{2})/([0-9]{2})/([0-9]{4})#\3-\1-\2#g' dates.txt
# 將Python的print語句改為函數
sed -E 's/print ([^\(].*)/print(\1)/g' script.py
使用更具體的字符類:
[0-9]
代替\d
(BRE中)[a-zA-Z]
代替\w
當不需要數字和下劃線時避免貪婪匹配:
.*?
進行非貪婪匹配(ERE)錨定優化: “`bash
grep “pattern” file
# 較快(如果pattern通常出現在行首) grep “^.*pattern” file
### 5.2 常見陷阱與解決方案
1. **元字符轉義問題**:
```bash
# BRE中需要轉義+
grep "a\+b" file.txt
# ERE中不需要
grep -E "a+b" file.txt
貪婪匹配問題: “`bash
grep -o “.*” file.html
# 正確:非貪婪匹配 grep -o “.*?” file.html
3. **行尾包含換行符**:
```bash
# $匹配的是換行符前的位置
echo "test" | grep "test$" # 會匹配
工具 | 默認類型 | 支持ERE | 支持PCRE | 備注 |
---|---|---|---|---|
grep | BRE | -E | -P | 基礎工具 |
egrep | ERE | 是 | 否 | grep -E的別名 |
sed | BRE | -r/-E | 否 | 流編輯器 |
awk | ERE | 是 | 否 | 強大的文本處理工具 |
perl | PCRE | 是 | 是 | 最完整的正則實現 |
簡單搜索:grep
# 快速查找包含IP地址的行
grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' file
復雜替換:sed
# 將多空格替換為單空格
sed -E 's/[[:space:]]+/ /g' file
結構化數據處理:awk
# 統計不同HTTP狀態碼數量
awk '/\[[0-9]{2}\/[A-Za-z]{3}\/[0-9]{4}/ {print $9}' access.log | sort | uniq -c
最復雜需求:Perl
# 多行匹配與復雜替換
perl -0777 -pe 's/<!--.*?-->//gs' file.html
假設有如下日志格式:
123.45.67.89 - - [10/Oct/2023:14:32:45 +0800] "GET /products/1234 HTTP/1.1" 200 4325 "https://example.com" "Mozilla/5.0"
提取關鍵信息:
# 1. 提取訪問最多的URL路徑
grep -oE '"GET /[^ ]+' access.log | cut -d' ' -f2 | sort | uniq -c | sort -nr | head
# 2. 統計不同瀏覽器的訪問比例
grep -oE '" [^"]+"$' access.log | cut -d' ' -f2 | sort | uniq -c | sort -nr
# 3. 找出響應時間超過5秒的請求(假設日志包含響應時間)
grep -E '" 200 [0-9]{4} [0-9]{4,}"' access.log
將IMG_1234.jpg重命名為vacation_1234.jpg:
for file in IMG_*.jpg; do
newname=$(echo "$file" | sed -E 's/IMG_([0-9]+)/vacation_\1/')
mv "$file" "$newname"
done
驗證電子郵件格式:
grep -E '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$' emails.txt
驗證強密碼(至少8字符,含大小寫字母和數字):
grep -E '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{8,}$' passwords.txt
初級階段:
中級階段:
高級階段:
在線工具:
書籍:
Linux手冊:
man 7 regex # Linux正則表達式手冊
man grep # grep使用手冊
正則表達式是Linux文本處理的瑞士軍刀,雖然學習曲線較陡,但一旦掌握將極大提高工作效率。建議從簡單模式開始,逐步嘗試更復雜的表達式,并在實際工作中不斷實踐和優化。 “`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。