R 語言中 gsub
與正則表達式詳解(含 POSIX 與 Perl 風格實例)
在 R 語言中,字符串處理是非常常見的需求,R 語言中的 gsub()
函數則具有字符串替換的功能。本文將通過兩個實例,幫助你深入理解 R 的 gsub()
、POSIX 字符類、Perl 風格正則、以及一些常見的坑點與進階技巧。
文章目錄
- R 語言中 `gsub` 與正則表達式詳解(含 POSIX 與 Perl 風格實例)
- 1 基礎實例:POSIX 字符類
- 1.1 `gsub()` 函數的語法規則
- 1.2 模式 `"[[:alpha:]]+"`
- 1.3 替換串 `"$"`
- 1.4 匹配過程
- 2 Perl 風格實例:`\\b\\w+\\b`
- 2.1 `perl = TRUE`
- 2.2 模式 `\\b\\w+\\b`
- 2.3 替換串 `"$"`
- 2.4 匹配過程
- 3 常見坑與進階
- 3.1 標點與連字符
- 3.2 數字與下劃線
- 3.3 Unicode 與多語言
- 3.4 只替換首個或限定長度
- 4 總結
1 基礎實例:POSIX 字符類
來看第一個例子:
gsub("[[:alpha:]]+", "$", "Two words")
# [1] "$ $"
1.1 gsub()
函數的語法規則
- 語法:
gsub(pattern, replacement, x, ...)
- 作用:將字符串
x
中 所有(global)匹配pattern
的部分替換為replacement
。
對應的sub()
只會替換第一個匹配。
1.2 模式 "[[:alpha:]]+"
[[:alpha:]]
:POSIX 命名字符類,表示“字母字符”,等價于 A–Z / a–z(并受 locale/編碼影響)。- 外層方括號
[...]
:字符類,匹配其中任意一個字符。 +
:量詞,表示“前面的模式重復一次或多次”。- 綜合上述兩點:
[[:alpha:]]+
匹配“一串連續字母”。
1.3 替換串 "$"
- 在 replacement 里,
$
是字面量,不會觸發正則引用。 - 注意,在 R 的分組回溯引用用的是
\\1
、\\2
…,不是$1
。
1.4 匹配過程
"Two words"
中:
Two
→ 匹配 → 替換為$
- 空格保留
words
→ 匹配 → 替換為$
結果:"$ $"
2 Perl 風格實例:\\b\\w+\\b
再看一個更靈活的例子,使用 Perl 風格正則:
gsub("\\b\\w+\\b", "$", "Two words", perl = TRUE)
# [1] "$ $"
2.1 perl = TRUE
- 啟用 PCRE(Perl-Compatible Regular Expressions)引擎。
- 支持
\\b
、\\w
、前后查看等高級語法。
2.2 模式 \\b\\w+\\b
注意:在 R 字符串中反斜杠需要轉義,所以正則
\b
要寫成\\b
。
\\b
:單詞邊界(word boundary),匹配位置,不消耗字符。\\w
:單詞字符,等價于[A-Za-z0-9_]
。+
:匹配一個或多個單詞字符。- 綜合:匹配“完整單詞”,即兩側是邊界的
\\w+
。
2.3 替換串 "$"
-
同樣是字面量
$
。 -
若要保留原文,需要捕獲組:
gsub("(\\b\\w+\\b)", "<\\1>", "Two words", perl=TRUE) # "<Two> <words>"
2.4 匹配過程
"Two words"
:
- 起始處 → 邊界 →
Two
匹配 →$
- 空格保留
words
匹配 →$
結果:"$ $"
其實前面所舉的兩個例子稍加改編后可以用來統計一段文本的單詞數,請讀者思考如何編寫 R 語言代碼可以實現這個功能?🤔
歡迎讀者在評論區分享你的代碼!
3 常見坑與進階
3.1 標點與連字符
-
\\w
不包含連字符-
、撇號'
:gsub("\\b\\w+\\b", "$", "don't well-known", perl=TRUE) # "$ $" (don 和 t;well 和 known)
-
想把它們算作詞的一部分:
gsub("\\b[\\w'-]+\\b", "$", "don't well-known", perl=TRUE)
3.2 數字與下劃線
-
\\w
包含數字與_
。若只想匹配純字母詞:gsub("\\p{L}+", "$", "C3PO and über", perl=TRUE)
3.3 Unicode 與多語言
-
默認
\\w
偏向 ASCII,不適合中文/重音字母。 -
更穩的方法是使用 Unicode 屬性:
gsub("\\p{L}+", "$", "über fa?ade 中 文", perl=TRUE)
-
或用
(*UCP)
提示 PCRE 按 Unicode 分類:gsub("(*UCP)\\b[\\p{L}\\p{N}_]+\\b", "$", "über fa?ade 中文", perl=TRUE)
3.4 只替換首個或限定長度
-
替換首個詞:
sub("\\b\\w+\\b", "$", "Two words", perl=TRUE)
-
替換長度 ≥4 的詞:
gsub("\\b(?=\\w{4,}\\b)\\w+\\b", "$", "a few longerwords", perl=TRUE)
4 總結
gsub()
= 全局替換,sub()
= 只進行首次替換。- POSIX 字符類(如
[[:alpha:]]
)適合基礎 ASCII 場景。 perl=TRUE
開啟 PCRE,引入\\b
、\\w
、前后查看等高級特性。- 替換串中
$
是普通字符;回溯引用用\\1
。 - 多語言/特殊符號場景下,建議使用
\\p{...}
與(*UCP)
。