新聞中心
正則表達式是一種進行模式匹配和文本操縱的復(fù)雜而又強大的工具。雖然正則表達式比純粹的文本匹配效率低,但是它卻更靈活,按照它的語法規(guī)則,根據(jù)需求構(gòu)造出的正則表達式能夠從原始文本中篩選出幾乎任何你想要得到的字符組合。

Go語言通過 regexp 包為正則表達式提供了官方支持,其采用 RE2 語法,除了
\c、
\C外,Go語言和 Perl、 Python 等語言的正則基本一致。
正則表達式語法規(guī)則
正則表達式是由普通字符(例如字符 a 到 z)以及特殊字符(稱為"元字符")構(gòu)成的文字序列,可以是單個的字符、字符集合、字符范圍、字符間的選擇或者所有這些組件的任意組合。
下面的表格中列舉了構(gòu)成正則表達式的一些語法規(guī)則及其含義。
1) 字符
| 語法 | 說明 | 表達式示例 | 匹配結(jié)果 |
|---|---|---|---|
| 一般字符 | 匹配自身 | abc | abc |
| . | 匹配任意除換行符"\n"外的字符, 在 DOTALL 模式中也能匹配換行符 | a.c | abc |
| \ | 轉(zhuǎn)義字符,使后一個字符改變原來的意思; 如果字符串中有字符 * 需要匹配,可以使用 \* 或者字符集[*]。 |
a\.c a\\c |
a.c a\c |
| [...] | 字符集(字符類),對應(yīng)的位置可以是字符集中任意字符。 字符集中的字符可以逐個列出,也可以給出范圍,如 [abc] 或 [a-c], 第一個字符如果是 ^ 則表示取反,如 [^abc] 表示除了abc之外的其他字符。 |
a[bcd]e | abe 或 ace 或 ade |
| \d | 數(shù)字:[0-9] | a\dc | a1c |
| \D | 非數(shù)字:[^\d] | a\Dc | abc |
| \s | 空白字符:[<空格>\t\r\n\f\v] | a\sc | a c |
| \S | 非空白字符:[^\s] | a\Sc | abc |
| \w | 單詞字符:[A-Za-z0-9] | a\wc | abc |
| \W | 非單詞字符:[^\w] | a\Wc | a c |
2) 數(shù)量詞(用在字符或 (...) 之后)
| 語法 | 說明 | 表達式示例 | 匹配結(jié)果 |
|---|---|---|---|
| * | 匹配前一個字符 0 或無限次 | abc* | ab 或 abccc |
| + | 匹配前一個字符 1 次或無限次 | abc+ | abc 或 abccc |
| ? | 匹配前一個字符 0 次或 1 次 | abc? | ab 或 abc |
| {m} | 匹配前一個字符 m 次 | ab{2}c | abbc |
| {m,n} | 匹配前一個字符 m 至 n 次,m 和 n 可以省略,若省略 m,則匹配 0 至 n 次; 若省略 n,則匹配 m 至無限次 |
ab{1,2}c | abc 或 abbc |
3) 邊界匹配
| 語法 | 說明 | 表達式示例 | 匹配結(jié)果 |
|---|---|---|---|
| ^ | 匹配字符串開頭,在多行模式中匹配每一行的開頭 | ^abc | abc |
| $ | 匹配字符串末尾,在多行模式中匹配每一行的末尾 | abc$ | abc |
| \A | 僅匹配字符串開頭 | \Aabc | abc |
| \Z | 僅匹配字符串末尾 | abc\Z | abc |
| \b | 匹配 \w 和 \W 之間 | a\b!bc | a!bc |
| \B | [^\b] | a\Bbc | abc |
4) 邏輯、分組
| 語法 | 說明 | 表達式示例 | 匹配結(jié)果 |
|---|---|---|---|
| | | | 代表左右表達式任意匹配一個,優(yōu)先匹配左邊的表達式 | abc|def | abc 或 def |
| (...) | 括起來的表達式將作為分組,分組將作為一個整體,可以后接數(shù)量詞 | (abc){2} | abcabc |
| (?P |
分組,功能與 (...) 相同,但會指定一個額外的別名 | (?P |
abcabc |
| \ |
引用編號為 |
(\d)abc\1 | 1abe1 或 5abc5 |
| (?P=name) | 引用別名為 |
(?P |
1abe1 或 5abc5 |
5) 特殊構(gòu)造(不作為分組)
| 語法 | 說明 | 表達式示例 | 匹配結(jié)果 |
|---|---|---|---|
| (?:...) | (…) 的不分組版本,用于使用 "|" 或后接數(shù)量詞 | (?:abc){2} | abcabc |
| (?iLmsux) | iLmsux 中的每個字符代表一種匹配模式,只能用在正則表達式的開頭,可選多個 | (?i)abc | AbC |
| (?#...) | # 后的內(nèi)容將作為注釋被忽略。 | abc(?#comment)123 | abc123 |
| (?=...) | 之后的字符串內(nèi)容需要匹配表達式才能成功匹配 | a(?=\d) | 后面是數(shù)字的 a |
| (?!...) | 之后的字符串內(nèi)容需要不匹配表達式才能成功匹配 | a(?!\d) | 后面不是數(shù)字的 a |
| (?<=...) | 之前的字符串內(nèi)容需要匹配表達式才能成功匹配 | (?<=\d)a | 前面是數(shù)字的a |
| (? | 之前的字符串內(nèi)容需要不匹配表達式才能成功匹配 | (? | 前面不是數(shù)字的a |
Regexp 包的使用
下面通過幾個示例來演示一下 regexp 包的使用。
【示例 1】匹配指定類型的字符串。
package main
import (
"fmt"
"regexp"
)
func main() {
buf := "abc azc a7c aac 888 a9c tac"
//解析正則表達式,如果成功返回解釋器
reg1 := regexp.MustCompile(`a.c`)
if reg1 == nil {
fmt.Println("regexp err")
return
}
//根據(jù)規(guī)則提取關(guān)鍵信息
result1 := reg1.FindAllStringSubmatch(buf, -1)
fmt.Println("result1 = ", result1)
}運行結(jié)果如下:
result1 = [[abc] [azc] [a7c] [aac] [a9c]]
【示例 2】匹配 a 和 c 中間包含一個數(shù)字的字符串。
package main
import (
"fmt"
"regexp"
)
func main() {
buf := "abc azc a7c aac 888 a9c tac"
//解析正則表達式,如果成功返回解釋器
reg1 := regexp.MustCompile(`a[0-9]c`)
if reg1 == nil { //解釋失敗,返回nil
fmt.Println("regexp err")
return
}
//根據(jù)規(guī)則提取關(guān)鍵信息
result1 := reg1.FindAllStringSubmatch(buf, -1)
fmt.Println("result1 = ", result1)
}運行結(jié)果如下:
result1 = [[a7c] [a9c]]
【示例 3】使用 \d 來匹配 a 和 c 中間包含一個數(shù)字的字符串。
package main
import (
"fmt"
"regexp"
)
func main() {
buf := "abc azc a7c aac 888 a9c tac"
//解析正則表達式,如果成功返回解釋器
reg1 := regexp.MustCompile(`a\dc`)
if reg1 == nil { //解釋失敗,返回nil
fmt.Println("regexp err")
return
}
//根據(jù)規(guī)則提取關(guān)鍵信息
result1 := reg1.FindAllStringSubmatch(buf, -1)
fmt.Println("result1 = ", result1)
}運行結(jié)果如下:
result1 = [[a7c] [a9c]]
【示例 4】匹配字符串中的小數(shù)。
package main
import (
"fmt"
"regexp"
)
func main() {
buf := "43.14 567 agsdg 1.23 7. 8.9 1sdljgl 6.66 7.8 "
//解釋正則表達式
reg := regexp.MustCompile(`\d+\.\d+`)
if reg == nil {
fmt.Println("MustCompile err")
return
}
//提取關(guān)鍵信息
//result := reg.FindAllString(buf, -1)
result := reg.FindAllStringSubmatch(buf, -1)
fmt.Println("result = ", result)
}運行結(jié)果如下:
result = [[43.14] [1.23] [8.9] [6.66] [7.8]]
【示例 5】匹配 div 標簽中的內(nèi)容。
package main
import (
"fmt"
"regexp"
)
func main() {
// 原生字符串
buf := `
C語言中文網(wǎng) | Go語言入門教程
Go語言簡介
Go語言基本語法
Go語言變量的聲明
Go語言教程簡明版
Go語言容器
Go語言函數(shù)
`
//解釋正則表達式
reg := regexp.MustCompile(`(?s:(.*?))`)
if reg == nil {
fmt.Println("MustCompile err")
return
}
//提取關(guān)鍵信息
result := reg.FindAllStringSubmatch(buf, -1)
//過濾<>>
for _, text := range result {
fmt.Println("text[1] = ", text[1])
}
}運行結(jié)果如下:
text[1] = Go語言簡介
text[1] = Go語言基本語法
Go語言變量的聲明
Go語言教程簡明版
text[1] = Go語言容器
text[1] = Go語言函數(shù)
【示例 6】通過 Compile 方法返回一個 Regexp 對象,實現(xiàn)匹配,查找,替換相關(guān)的功能。
package main
import (
"fmt"
"regexp"
"strconv"
)
func main() {
//目標字符串
searchIn := "John: 2578.34 William: 4567.23 Steve: 5632.18"
pat := "[0-9]+.[0-9]+" //正則
f := func(s string) string{
v, _ := strconv.ParseFloat(s, 32)
return strconv.FormatFloat(v * 2, 'f', 2, 32)
}
if ok, _ := regexp.Match(pat, []byte(searchIn)); ok {
fmt.Println("Match Found!")
}
re, _ := regexp.Compile(pat)
//將匹配到的部分替換為 "##.#"
str := re.ReplaceAllString(searchIn, "##.#")
fmt.Println(str)
//參數(shù)為函數(shù)時
str2 := re.ReplaceAllStringFunc(searchIn, f)
fmt.Println(str2)
}輸出結(jié)果:
Match Found!
John: ##.# William: ##.# Steve: ##.#
John: 5156.68 William: 9134.46 Steve: 11264.36
上面代碼中 Compile 方法可以解析并返回一個正則表達式,如果成功返回,則說明該正則表達式正確可用于匹配文本。
另外我們也可以使用 MustCompile 方法,它也可以像 Compile 方法一樣檢驗正則的有效性,但是當正則不合法時程序?qū)?panic。
網(wǎng)站標題:創(chuàng)新互聯(lián)GO教程:Go語言正則表達式:regexp包
轉(zhuǎn)載來源:http://fisionsoft.com.cn/article/dpcoopp.html


咨詢
建站咨詢
