------------------------------------------------------------
Golang中的正規表達式
------------------------------------------------------------
用法:
------------------------------
單一:
. 比對任意一個字元,如果設定 s = true,則可以比對換行符
[字元類] 比對“字元類”中的一個字元,“字元類”見後面的說明
[^字元類] 比對“字元類”外的一個字元,“字元類”見後面的說明
\小寫Perl标記 比對“Perl類”中的一個字元,“Perl類”見後面的說明
\大寫Perl标記 比對“Perl類”外的一個字元,“Perl類”見後面的說明
[:ASCII類名:] 比對“ASCII類”中的一個字元,“ASCII類”見後面的說明
[:^ASCII類名:] 比對“ASCII類”外的一個字元,“ASCII類”見後面的說明
\pUnicode普通類名 比對“Unicode類”中的一個字元(僅普通類),“Unicode類”見後面的說明
\PUnicode普通類名 比對“Unicode類”外的一個字元(僅普通類),“Unicode類”見後面的說明
\p{Unicode類名} 比對“Unicode類”中的一個字元,“Unicode類”見後面的說明
\P{Unicode類名} 比對“Unicode類”外的一個字元,“Unicode類”見後面的說明
------------------------------
複合:
xy 比對 xy(x 後面跟随 y)
x|y 比對 x 或 y (優先比對 x)
------------------------------
重複:
x* 比對零個或多個 x,優先比對更多(貪婪)
x+ 比對一個或多個 x,優先比對更多(貪婪)
x? 比對零個或一個 x,優先比對一個(貪婪)
x{n,m} 比對 n 到 m 個 x,優先比對更多(貪婪)
x{n,} 比對 n 個或多個 x,優先比對更多(貪婪)
x{n} 隻比對 n 個 x
x*? 比對零個或多個 x,優先比對更少(非貪婪)
x+? 比對一個或多個 x,優先比對更少(非貪婪)
x?? 比對零個或一個 x,優先比對零個(非貪婪)
x{n,m}? 比對 n 到 m 個 x,優先比對更少(非貪婪)
x{n,}? 比對 n 個或多個 x,優先比對更少(非貪婪)
x{n}? 隻比對 n 個 x
------------------------------
分組:
(子表達式) 被捕獲的組,該組被編号 (子比對)
(?P<命名>子表達式) 被捕獲的組,該組被編号且被命名 (子比對)
(?:子表達式) 非捕獲的組 (子比對)
(?标記) 在組内設定标記,非捕獲,标記影響目前組後的正規表達式
(?标記:子表達式) 在組内設定标記,非捕獲,标記影響目前組内的子表達式
标記的文法是:
xyz (設定 xyz 标記)
-xyz (清除 xyz 标記)
xy-z (設定 xy 标記, 清除 z 标記)
可以設定的标記有:
i 不區分大小寫 (預設為 false)
m 多行模式:讓 ^ 和 $ 比對整個文本的開頭和結尾,而非行首和行尾(預設為 false)
s 讓 . 比對 \n (預設為 false)
U 非貪婪模式:交換 x* 和 x*? 等的含義 (預設為 false)
------------------------------
位置标記:
^ 如果标記 m=true 則比對行首,否則比對整個文本的開頭(m 預設為 false)
$ 如果标記 m=true 則比對行尾,否則比對整個文本的結尾(m 預設為 false)
\A 比對整個文本的開頭,忽略 m 标記
\b 比對單詞邊界
\B 比對非單詞邊界
\z 比對整個文本的結尾,忽略 m 标記
------------------------------
轉義序列:
\a 比對響鈴符 (相當于 \x07)
注意:正規表達式中不能使用 \b 比對倒退符,因為 \b 被用來比對單詞邊界,
可以使用 \x08 表示倒退符。
\f 比對換頁符 (相當于 \x0C)
\t 比對橫向制表符(相當于 \x09)
\n 比對換行符 (相當于 \x0A)
\r 比對回車符 (相當于 \x0D)
\v 比對縱向制表符(相當于 \x0B)
\123 比對 8 進制編碼所代表的字元(必須是 3 位數字)
\x7F 比對 16 進制編碼所代表的字元(必須是 3 位數字)
\x{10FFFF} 比對 16 進制編碼所代表的字元(最大值 10FFFF )
\Q...\E 比對 \Q 和 \E 之間的文本,忽略文本中的正則文法
\\ 比對字元 \
\^ 比對字元 ^
\$ 比對字元 $
\. 比對字元 .
\* 比對字元 *
\+ 比對字元 +
\? 比對字元 ?
\{ 比對字元 {
\} 比對字元 }
\( 比對字元 (
\) 比對字元 )
\[ 比對字元 [
\] 比對字元 ]
\| 比對字元 |
------------------------------
可以将“命名字元類”作為“字元類”的元素:
[\d] 比對數字 (相當于 \d)
[^\d] 比對非數字 (相當于 \D)
[\D] 比對非數字 (相當于 \D)
[^\D] 比對數字 (相當于 \d)
[[:name:]] 命名的“ASCII 類”包含在“字元類”中 (相當于 [:name:])
[^[:name:]] 命名的“ASCII 類”不包含在“字元類”中 (相當于 [:^name:])
[\p{Name}] 命名的“Unicode 類”包含在“字元類”中 (相當于 \p{Name})
[^\p{Name}] 命名的“Unicode 類”不包含在“字元類”中 (相當于 \P{Name})
------------------------------------------------------------
說明:
------------------------------
“字元類”取值如下(“字元類”包含“Perl類”、“ASCII類”、“Unicode類”):
x 單個字元
A-Z 字元範圍(包含首尾字元)
\小寫字母 Perl類
[:ASCII類名:] ASCII類
\p{Unicode腳本類名} Unicode類 (腳本類)
\pUnicode普通類名 Unicode類 (普通類)
------------------------------
“Perl 類”取值如下:
\d 數字 (相當于 [0-9])
\D 非數字 (相當于 [^0-9])
\s 空白 (相當于 [\t\n\f\r ])
\S 非空白 (相當于[^\t\n\f\r ])
\w 單詞字元 (相當于 [0-9A-Za-z_])
\W 非單詞字元 (相當于 [^0-9A-Za-z_])
------------------------------
“ASCII 類”取值如下
[:alnum:] 字母數字 (相當于 [0-9A-Za-z])
[:alpha:] 字母 (相當于 [A-Za-z])
[:ascii:] ASCII 字元集 (相當于 [\x00-\x7F])
[:blank:] 空白占位符 (相當于 [\t ])
[:cntrl:] 控制字元 (相當于 [\x00-\x1F\x7F])
[:digit:] 數字 (相當于 [0-9])
[:graph:] 圖形字元 (相當于 [!-~])
[:lower:] 小寫字母 (相當于 [a-z])
[:print:] 可列印字元 (相當于 [ -~] 相當于 [ [:graph:]])
[:punct:] 标點符号 (相當于 [!-/:-@[-反引号{-~])
[:space:] 空白字元(相當于 [\t\n\v\f\r ])
[:upper:] 大寫字母(相當于 [A-Z])
[:word:] 單詞字元(相當于 [0-9A-Za-z_])
[:xdigit:] 16 進制字元集(相當于 [0-9A-Fa-f])
------------------------------
“Unicode 類”取值如下---普通類:
C -其他- (other)
Cc 控制字元 (control)
Cf 格式 (format)
Co 私人使用區 (private use)
Cs 代理區 (surrogate)
L -字母- (letter)
Ll 小寫字母 (lowercase letter)
Lm 修飾字母 (modifier letter)
Lo 其它字母 (other letter)
Lt 首字母大寫字母 (titlecase letter)
Lu 大寫字母 (uppercase letter)
M -标記- (mark)
Mc 間距标記 (spacing mark)
Me 關閉标記 (enclosing mark)
Mn 非間距标記 (non-spacing mark)
N -數字- (number)
Nd 十進制數字 (decimal number)
Nl 字母數字 (letter number)
No 其它數字 (other number)
P -标點- (punctuation)
Pc 連接配接符标點 (connector punctuation)
Pd 破折号标點符号 (dash punctuation)
Pe 關閉的标點符号 (close punctuation)
Pf 最後的标點符号 (final punctuation)
Pi 最初的标點符号 (initial punctuation)
Po 其他标點符号 (other punctuation)
Ps 開放的标點符号 (open punctuation)
S -符号- (symbol)
Sc 貨币符号 (currency symbol)
Sk 修飾符号 (modifier symbol)
Sm 數學符号 (math symbol)
So 其他符号 (other symbol)
Z -分隔符- (separator)
Zl 行分隔符 (line separator)
Zp 段落分隔符 (paragraph separator)
Zs 空白分隔符 (space separator)
------------------------------
“Unicode 類”取值如下---腳本類:
Arabic 阿拉伯文
Armenian 亞美尼亞文
Balinese 巴厘島文
Bengali 孟加拉文
Bopomofo 漢語拼音字母
Braille 盲文
Buginese 布吉文
Buhid 布希德文
Canadian_Aboriginal 加拿大土著文
Carian 卡裡亞文
Cham 占族文
Cherokee 切諾基文
Common 普通的,字元不是特定于一個腳本
Coptic 科普特文
Cuneiform 楔形文字
Cypriot 塞普勒斯文
Cyrillic 斯拉夫文
Deseret 猶他州文
Devanagari 梵文
Ethiopic 衣索匹亞文
Georgian 格魯吉亞文
Glagolitic 格拉哥裡文
Gothic 哥特文
Greek 希臘
Gujarati 古吉拉特文
Gurmukhi 果魯穆奇文
Han 漢文
Hangul 韓文
Hanunoo 哈魯喏文
Hebrew 希伯來文
Hiragana 平假名(日語)
Inherited 繼承前一個字元的腳本
Kannada 坎那達文
Katakana 片假名(日語)
Kayah_Li 克耶字母
Kharoshthi 卡羅須提文
Khmer 高棉文
Lao 寮國文
Latin 拉丁文
Lepcha 雷布查文
Limbu 林布文
Linear_B B類線形文字(古希臘)
Lycian 利西亞文
Lydian 呂底亞文
Malayalam 馬拉雅拉姆文
Mongolian 蒙古文
Myanmar 緬甸文
New_Tai_Lue 新傣仂文
Nko Nko文
Ogham 歐甘文
Ol_Chiki 桑塔利文
Old_Italic 古意大利文
Old_Persian 古波斯文
Oriya 奧裡亞文
Osmanya 奧斯曼亞文
Phags_Pa 八思巴文
Phoenician 腓尼基文
Rejang 拉讓文
Runic 古代北歐文字
Saurashtra 索拉什特拉文(印度縣城)
Shavian 蕭伯納文
Sinhala 僧伽羅文
Sundanese 巽他文
Syloti_Nagri 錫爾赫特文
Syriac 叙利亞文
Tagalog 塔加拉文
Tagbanwa 塔格巴努亞文
Tai_Le 德宏傣文
Tamil 泰米爾文
Telugu 泰盧固文
Thaana 塔安那文
Thai 泰文
Tibetan 藏文
Tifinagh 提非納文
Ugaritic 烏加裡特文
Vai 瓦伊文
Yi 彜文
------------------------------------------------------------
注意:
對于 [a-z] 這樣的正規表達式,如果要在 [] 中比對 - ,可以将 - 放在 [] 的開頭或結尾,例如 [-a-z] 或 [a-z-]
可以在 [] 中使用轉義字元:\f、\t、\n、\r、\v、\377、\xFF、\x{10FFFF}、\\、\^、\$、\.、\*、\+、\?、\{、\}、\(、\)、\[、\]、\|(具體含義見上面的說明)
如果在正規表達式中使用了分組,則在執行正則替換的時候,“替換内容”中可以使用 $1、${1}、$name、${name} 這樣的“分組引用符”擷取相應的分組内容。其中 $0 代表整個比對項,$1 代表第 1 個分組,$2 代表第 2 個分組,……。
如果“分組引用符”是 $name 的形式,則在解析的時候,name 是取盡可能長的字元串,比如:$1x 相當于 ${1x},而不是${1}x,再比如:$10 相當于 ${10},而不是 ${1}0。
由于 $ 字元會被轉義,是以要在“替換内容”中使用 $ 字元,可以用 \$ 代替。
上面介紹的正規表達式文法是“Perl 文法”,除了“Perl 文法”外,Go 語言中還有另一種“POSIX 文法”,“POSIX 文法”除了不能使用“Perl 類”之外,其它都一樣。
------------------------------------------------------------
// 示例
func main() {
text := `Hello 世界!123 Go.`
// 查找連續的小寫字母
reg := regexp.MustCompile(`[a-z]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["ello" "o"]
// 查找連續的非小寫字母
reg = regexp.MustCompile(`[^a-z]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["H" " 世界!123 G" "."]
// 查找連續的單詞字母
reg = regexp.MustCompile(`[\w]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Hello" "123" "Go"]
// 查找連續的非單詞字母、非空白字元
reg = regexp.MustCompile(`[^\w\s]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["世界!" "."]
// 查找連續的大寫字母
reg = regexp.MustCompile(`[[:upper:]]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["H" "G"]
// 查找連續的非 ASCII 字元
reg = regexp.MustCompile(`[[:^ascii:]]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["世界!"]
// 查找連續的标點符号
reg = regexp.MustCompile(`[\pP]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["!" "."]
// 查找連續的非标點符号字元
reg = regexp.MustCompile(`[\PP]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Hello 世界" "123 Go"]
// 查找連續的漢字
reg = regexp.MustCompile(`[\p{Han}]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["世界"]
// 查找連續的非漢字字元
reg = regexp.MustCompile(`[\P{Han}]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Hello " "!123 Go."]
// 查找 Hello 或 Go
reg = regexp.MustCompile(`Hello|Go`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Hello" "Go"]
// 查找行首以 H 開頭,以空格結尾的字元串
reg = regexp.MustCompile(`^H.*\s`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Hello 世界!123 "]
// 查找行首以 H 開頭,以空白結尾的字元串(非貪婪模式)
reg = regexp.MustCompile(`(?U)^H.*\s`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Hello "]
// 查找以 hello 開頭(忽略大小寫),以 Go 結尾的字元串
reg = regexp.MustCompile(`(?i:^hello).*Go`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Hello 世界!123 Go"]
// 查找 Go.
reg = regexp.MustCompile(`\QGo.\E`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Go."]
// 查找從行首開始,以空格結尾的字元串(非貪婪模式)
reg = regexp.MustCompile(`(?U)^.* `)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Hello "]
// 查找以空格開頭,到行尾結束,中間不包含空格字元串
reg = regexp.MustCompile(` [^ ]*$`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// [" Go."]
// 查找“單詞邊界”之間的字元串
reg = regexp.MustCompile(`(?U)\b.+\b`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Hello" " 世界!" "123" " " "Go"]
// 查找連續 1 次到 4 次的非空格字元,并以 o 結尾的字元串
reg = regexp.MustCompile(`[^ ]{1,4}o`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Hello" "Go"]
// 查找 Hello 或 Go
reg = regexp.MustCompile(`(?:Hell|G)o`)
fmt.Printf("%q\n", reg.FindAllString(text, -1))
// ["Hello" "Go"]
// 查找 Hello 或 Go,替換為 Hellooo、Gooo
reg = regexp.MustCompile(`(?PHell|G)o`)
fmt.Printf("%q\n", reg.ReplaceAllString(text, "${n}ooo"))
// "Hellooo 世界!123 Gooo."
// 交換 Hello 和 Go
reg = regexp.MustCompile(`(Hello)(.*)(Go)`)
fmt.Printf("%q\n", reg.ReplaceAllString(text, "$3$2$1"))
// "Go 世界!123 Hello."
// 特殊字元的查找
reg = regexp.MustCompile(`[\f\t\n\r\v\123\x7F\x{10FFFF}\\\^\$\.\*\+\?\{\}\(\)\[\]\|]`)
fmt.Printf("%q\n", reg.ReplaceAllString("\f\t\n\r\v\123\x7F\U0010FFFF\\^$.*+?{}()[]|", "-"))
// "----------------------"
}
------------------------------------------------------------
完
複制