当前位置: 首页 > news >正文

Go语言学习笔记——正则表达式

文章目录

  • Golang正则表达式
    • Golang正则表达式语法
      • 单一
      • 复合
      • 重复
      • 分组
      • 位置标记
      • 转义序列
      • 可以将“命名字符类”作为“字符类”的元素
      • `Perl 类`取值如下
      • `ASCII 类`取值如下
      • `Unicode 类`取值如下---普通类
      • `Unicode 类`取值如下---脚本类
    • Golang正则入门实例
    • 综合实例演示


Golang正则表达式

正则表达式,(英语:Regular Expression,在代码中常简写为regex、regexp或RE),正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。例如:用户注册,邮箱验证、手机号码验证、爬虫字符串匹配等。

Golang正则表达式语法

官方文档:

go doc regexp/syntax

单一

示例备注
.匹配任意一个字符,如果设置 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:])
[1]命名的“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:]      图形字符 (相当于 [!-~] 相当于 [A-Za-z0-9!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])
[: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、 1{1}、 n a m e 、 name、 name{name} 这样的“分组引用符”获取相应的分组内容。其中 $0 代表整个匹配项,$1 代表第 1 个分组,$2 代表第 2 个分组,……。
  • 如果“分组引用符”是 $name 的形式,则在解析的时候,name 是取尽可能长的字符串,比如:$1x 相当于 1 x ,而不是 {1x},而不是 1x,而不是{1}x,再比如:$10 相当于 ${10},而不是 ${1}0。
  • 由于 $ 字符会被转义,所以要在“替换内容”中使用 $ 字符,可以用 $ 代替。
  • 上面介绍的正则表达式语法是“Perl 语法”,除了“Perl 语法”外,Go 语言中还有另一种“POSIX 语法”,“POSIX 语法”除了不能使用“Perl 类”之外,其它都一样。

Golang正则入门实例

package main

import (
	"fmt"
	"regexp"
)

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(`(?:Hell|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\\^$.*+?{}()[]|", "-"))
}

运行结果:

[Running] go run "e:\golang开发学习\go_pro\main.go"
["ello" "o"]
["H" " 世界!123 G" "."]
["Hello" "123" "Go"]
["世界!" "."]
["H" "G"]
["世界"]
["!" "."]
["Hello 世界" "123 Go"]
["世界"]
["Hello " "!123 Go."]
["Hello" "Go"]
["Hello 世界!123 "]
["Hello "]
["Hello 世界!123 Go"]
["Go."]
["Hello "]
[" Go."]
["Hello" " 世界!" "123" " " "Go"]
["Hello" "Go"]
["Hello" "Go"]
"ooo 世界!123 ooo."
"Go 世界!123 Hello."
"\f\t\n\r\vS\u007f\U0010ffff\\^$.*+?{}()[-|"

[Done] exited with code=0 in 1.041 seconds

综合实例演示

  • func Match(pattern string, b []byte) (matched bool, err error)

    // 判断在 b 中能否找到正则表达式 pattern 所匹配的子串
    
    // pattern:要查找的正则表达式
    
    // b:要在其中进行查找的 []byte
    
    // matched:返回是否找到匹配项
    
    // err:返回查找过程中遇到的任何错误
    
    // 此函数通过调用 Regexp 的方法实现
    
    func main() {
    
    fmt.Println(regexp.Match("H.* ", []byte("Hello World!")))
    
    // true
    
    }
    
  • func MatchReader(pattern string, r io.RuneReader) (matched bool, err error)

    // 判断在 r 中能否找到正则表达式 pattern 所匹配的子串
    
    // pattern:要查找的正则表达式
    
    // r:要在其中进行查找的 RuneReader 接口
    
    // matched:返回是否找到匹配项
    
    // err:返回查找过程中遇到的任何错误
    
    // 此函数通过调用 Regexp 的方法实现
    
    func main() {
    
    r := bytes.NewReader([]byte("Hello World!"))
    
    fmt.Println(regexp.MatchReader("H.* ", r))
    
    // true
    
    }
    
  • func MatchString(pattern string, s string) (matched bool, err error)

    // 判断在 s 中能否找到正则表达式 pattern 所匹配的子串
    
    // pattern:要查找的正则表达式
    
    // r:要在其中进行查找的字符串
    
    // matched:返回是否找到匹配项
    
    // err:返回查找过程中遇到的任何错误
    
    // 此函数通过调用 Regexp 的方法实现
    
    func main() {
    
    fmt.Println(regexp.Match("H.* ", "Hello World!"))
    
    // true
    
    }
    
  • func QuoteMeta(s string) string

    // QuoteMeta 将字符串 s 中的“特殊字符”转换为其“转义格式”
    
    // 例如,QuoteMeta(`[foo]`)返回``。
    
    // 特殊字符有:\.+*?()|[]{}^$
    
    // 这些字符用于实现正则语法,所以当作普通字符使用时需要转换
    
    func main() {
    
    fmt.Println(regexp.QuoteMeta("(?P:Hello) [a-z]"))
    
    }
    
    
  • func Compile(expr string) (*Regexp, error)

    // Compile 用来解析正则表达式 expr 是否合法,如果合法,则返回一个 Regexp 对象
    
    // Regexp 对象可以在任意文本上执行需要的操作
    
    func main() {
    
    reg, err := regexp.Compile(`\w+`)
    
    fmt.Printf("%q,%v\n", reg.FindString("Hello World!"), err)
    
    // "Hello",
    
    }
    
  • func CompilePOSIX(expr string) (*Regexp, error)

    // CompilePOSIX 的作用和 Compile 一样
    
    // 不同的是,CompilePOSIX 使用 POSIX 语法,
    
    // 同时,它采用最左最长方式搜索,
    
    // 而 Compile 采用最左最短方式搜索
    
    // POSIX 语法不支持 Perl 的语法格式:\d、\D、\s、\S、\w、\W
    
    func main() {
    
    reg, err := regexp.CompilePOSIX(`[[:word:]]+`)
    
    fmt.Printf("%q,%v\n", reg.FindString("Hello World!"), err)
    
    // "Hello"
    
    }
    
  • func MustCompile(str string) *Regexp

    // MustCompile 的作用和 Compile 一样
    
    // 不同的是,当正则表达式 str 不合法时,MustCompile 会抛出异常
    
    // 而 Compile 仅返回一个 error 值
    
    func main() {
    
    reg := regexp.MustCompile(`\w+`)
    
    fmt.Println(reg.FindString("Hello World!"))
    
    // Hello
    
    }
    
  • func MustCompilePOSIX(str string) *Regexp

    // MustCompilePOSIX 的作用和 CompilePOSIX 一样
    
    // 不同的是,当正则表达式 str 不合法时,MustCompilePOSIX 会抛出异常
    
    // 而 CompilePOSIX 仅返回一个 error 值
    
    func main() {
    
    reg := regexp.MustCompilePOSIX(`[[:word:]].+ `)
    
    fmt.Printf("%q\n", reg.FindString("Hello World!"))
    
    // "Hello "
    
    }
    
  • func (re *Regexp) Find(b []byte) []byte

    // 在 b 中查找 re 中编译好的正则表达式,并返回第一个匹配的内容
    
    func main() {
    
    reg := regexp.MustCompile(`\w+`)
    
    fmt.Printf("%q", reg.Find([]byte("Hello World!")))
    
    // "Hello"
    
    }
    
  • func (re *Regexp) FindString(s string) string

    // 在 s 中查找 re 中编译好的正则表达式,并返回第一个匹配的内容
    
    func main() {
    
    reg := regexp.MustCompile(`\w+`)
    
    fmt.Println(reg.FindString("Hello World!"))
    
    // "Hello"
    
    }
    
  • func (re *Regexp) FindAll(b []byte, n int) [][]byte

    // 在 b 中查找 re 中编译好的正则表达式,并返回所有匹配的内容
    
    // {{匹配项}, {匹配项}, ...}
    
    // 只查找前 n 个匹配项,如果 n < 0,则查找所有匹配项
    
    func main() {
    
    reg := regexp.MustCompile(`\w+`)
    
    fmt.Printf("%q", reg.FindAll([]byte("Hello World!"), -1))
    
    // ["Hello" "World"]
    
    }
    
  • func (re *Regexp) FindAllString(s string, n int) []string

    // 在 s 中查找 re 中编译好的正则表达式,并返回所有匹配的内容
    
    // {匹配项, 匹配项, ...}
    
    // 只查找前 n 个匹配项,如果 n < 0,则查找所有匹配项
    
    func main() {
    
    reg := regexp.MustCompile(`\w+`)
    
    fmt.Printf("%q", reg.FindAllString("Hello World!", -1))
    
    // ["Hello" "World"]
    
    }
    
  • func (re *Regexp) FindIndex(b []byte) (loc []int)

    // 在 b 中查找 re 中编译好的正则表达式,并返回第一个匹配的位置
    
    // {起始位置, 结束位置}
    
    func main() {
    
    reg := regexp.MustCompile(`\w+`)
    
    fmt.Println(reg.FindIndex([]byte("Hello World!")))
    
    // [0 5]
    
    }
    
  • func (re *Regexp) FindStringIndex(s string) (loc []int)

    // 在 s 中查找 re 中编译好的正则表达式,并返回第一个匹配的位置
    
    // {起始位置, 结束位置}
    
    func main() {
    
    reg := regexp.MustCompile(`\w+`)
    
    fmt.Println(reg.FindStringIndex("Hello World!"))
    
    // [0 5]
    
    }
    
  • func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int)

    // 在 r 中查找 re 中编译好的正则表达式,并返回第一个匹配的位置
    
    // {起始位置, 结束位置}
    
    func main() {
    
    r := bytes.NewReader([]byte("Hello World!"))
    
    reg := regexp.MustCompile(`\w+`)
    
    fmt.Println(reg.FindReaderIndex(r))
    
    // [0 5]
    
    }
    
  • func (re *Regexp) FindAllIndex(b []byte, n int) [][]int

    // 在 b 中查找 re 中编译好的正则表达式,并返回所有匹配的位置
    
    // {{起始位置, 结束位置}, {起始位置, 结束位置}, ...}
    
    // 只查找前 n 个匹配项,如果 n < 0,则查找所有匹配项
    
    func main() {
    
    reg := regexp.MustCompile(`\w+`)
    
    fmt.Println(reg.FindAllIndex([]byte("Hello World!"), -1))
    
    // [[0 5] [6 11]]
    
    }
    
  • func (re *Regexp) FindAllStringIndex(s string, n int) [][]int

    // 在 s 中查找 re 中编译好的正则表达式,并返回所有匹配的位置
    
    // {{起始位置, 结束位置}, {起始位置, 结束位置}, ...}
    
    // 只查找前 n 个匹配项,如果 n < 0,则查找所有匹配项
    
    func main() {
    
    reg := regexp.MustCompile(`\w+`)
    
    fmt.Println(reg.FindAllStringIndex("Hello World!", -1))
    
    // [[0 5] [6 11]]
    
    }
    
  • func (re *Regexp) FindSubmatch(b []byte) [][]byte

    // 在 b 中查找 re 中编译好的正则表达式,并返回第一个匹配的内容
    
    // 同时返回子表达式匹配的内容
    
    // {{完整匹配项}, {子匹配项}, {子匹配项}, ...}
    
    func main() {
    
    reg := regexp.MustCompile(`(\w)(\w)+`)
    
    fmt.Printf("%q", reg.FindSubmatch([]byte("Hello World!")))
    
    // ["Hello" "H" "o"]
    
    }
    
  • func (re *Regexp) FindStringSubmatch(s string) []string

    // 在 s 中查找 re 中编译好的正则表达式,并返回第一个匹配的内容
    
    // 同时返回子表达式匹配的内容
    
    // {完整匹配项, 子匹配项, 子匹配项, ...}
    
    func main() {
    
    reg := regexp.MustCompile(`(\w)(\w)+`)
    
    fmt.Printf("%q", reg.FindStringSubmatch("Hello World!"))
    
    // ["Hello" "H" "o"]
    
    }
    
  • func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte

    // 在 b 中查找 re 中编译好的正则表达式,并返回所有匹配的内容
    
    // 同时返回子表达式匹配的内容
    
    // {
    
    // {{完整匹配项}, {子匹配项}, {子匹配项}, ...},
    
    // {{完整匹配项}, {子匹配项}, {子匹配项}, ...},
    
    // ...
    
    // }
    
    func main() {
    
    reg := regexp.MustCompile(`(\w)(\w)+`)
    
    fmt.Printf("%q", reg.FindAllSubmatch([]byte("Hello World!"), -1))
    
    // [["Hello" "H" "o"] ["World" "W" "d"]]
    
    }
    
  • func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string

    // 在 s 中查找 re 中编译好的正则表达式,并返回所有匹配的内容
    
    // 同时返回子表达式匹配的内容
    
    // {
    
    // {完整匹配项, 子匹配项, 子匹配项, ...},
    
    // {完整匹配项, 子匹配项, 子匹配项, ...},
    
    // ...
    
    // }
    
    // 只查找前 n 个匹配项,如果 n < 0,则查找所有匹配项
    
    func main() {
    
    reg := regexp.MustCompile(`(\w)(\w)+`)
    
    fmt.Printf("%q", reg.FindAllStringSubmatch("Hello World!", -1))
    
    // [["Hello" "H" "o"] ["World" "W" "d"]]
    
    }
    
  • func (re *Regexp) FindSubmatchIndex(b []byte) []int

    // 在 b 中查找 re 中编译好的正则表达式,并返回第一个匹配的位置
    
    // 同时返回子表达式匹配的位置
    
    // {完整项起始, 完整项结束, 子项起始, 子项结束, 子项起始, 子项结束, ...}
    
    func main() {
    
    reg := regexp.MustCompile(`(\w)(\w)+`)
    
    fmt.Println(reg.FindSubmatchIndex([]byte("Hello World!")))
    
    // [0 5 0 1 4 5]
    
    }
    
  • func (re *Regexp) FindStringSubmatchIndex(s string) []int

    // 在 s 中查找 re 中编译好的正则表达式,并返回第一个匹配的位置
    
    // 同时返回子表达式匹配的位置
    
    // {完整项起始, 完整项结束, 子项起始, 子项结束, 子项起始, 子项结束, ...}
    
    func main() {
    
    reg := regexp.MustCompile(`(\w)(\w)+`)
    
    fmt.Println(reg.FindStringSubmatchIndex("Hello World!"))
    
    // [0 5 0 1 4 5]
    
    }
    
  • func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int

    // 在 r 中查找 re 中编译好的正则表达式,并返回第一个匹配的位置
    
    // 同时返回子表达式匹配的位置
    
    // {完整项起始, 完整项结束, 子项起始, 子项结束, 子项起始, 子项结束, ...}
    
    func main() {
    
    r := bytes.NewReader([]byte("Hello World!"))
    
    reg := regexp.MustCompile(`(\w)(\w)+`)
    
    fmt.Println(reg.FindReaderSubmatchIndex(r))
    
    // [0 5 0 1 4 5]
    
    }
    
  • func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int

    // 在 b 中查找 re 中编译好的正则表达式,并返回所有匹配的位置
    
    // 同时返回子表达式匹配的位置
    
    // {
    
    // {完整项起始, 完整项结束, 子项起始, 子项结束, 子项起始, 子项结束, ...},
    
    // {完整项起始, 完整项结束, 子项起始, 子项结束, 子项起始, 子项结束, ...},
    
    // ...
    
    // }
    
    // 只查找前 n 个匹配项,如果 n < 0,则查找所有匹配项
    
    func main() {
    
    reg := regexp.MustCompile(`(\w)(\w)+`)
    
    fmt.Println(reg.FindAllSubmatchIndex([]byte("Hello World!"), -1))
    
    // [[0 5 0 1 4 5] [6 11 6 7 10 11]]
    
    }
    
  • func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int

    // 在 s 中查找 re 中编译好的正则表达式,并返回所有匹配的位置
    
    // 同时返回子表达式匹配的位置
    
    // {
    
    // {完整项起始, 完整项结束, 子项起始, 子项结束, 子项起始, 子项结束, ...},
    
    // {完整项起始, 完整项结束, 子项起始, 子项结束, 子项起始, 子项结束, ...},
    
    // ...
    
    // }
    
    // 只查找前 n 个匹配项,如果 n < 0,则查找所有匹配项
    
    func main() {
    
    reg := regexp.MustCompile(`(\w)(\w)+`)
    
    fmt.Println(reg.FindAllStringSubmatchIndex("Hello World!", -1))
    
    // [[0 5 0 1 4 5] [6 11 6 7 10 11]]
    
    }
    
  • func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte

    // 将 template 的内容经过处理后,追加到 dst 的尾部。
    
    // template 中要有 $1、$2、${name1}、${name2} 这样的“分组引用符”
    
    // match 是由 FindSubmatchIndex 方法返回的结果,里面存放了各个分组的位置信息
    
    // 如果 template 中有“分组引用符”,则以 match 为标准,
    
    // 在 src 中取出相应的子串,替换掉 template 中的 $1、$2 等引用符号。
    
    func main() {
    
    reg := regexp.MustCompile(`(\w+),(\w+)`)
    
    src := []byte("Golang,World!") // 源文本
    
    dst := []byte("Say: ") // 目标文本
    
    template := []byte("Hello $1, Hello $2") // 模板
    
    match := reg.FindSubmatchIndex(src) // 解析源文本
    
    // 填写模板,并将模板追加到目标文本中
    
    fmt.Printf("%q", reg.Expand(dst, template, src, match))
    
    // "Say: Hello Golang, Hello World"
    
    }
    
  • func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte

    // 功能同 Expand 一样,只不过参数换成了 string 类型
    
    func main() {
    
    reg := regexp.MustCompile(`(\w+),(\w+)`)
    
    src := "Golang,World!" // 源文本
    
    dst := []byte("Say: ") // 目标文本(可写)
    
    template := "Hello $1, Hello $2" // 模板
    
    match := reg.FindStringSubmatchIndex(src) // 解析源文本
    
    // 填写模板,并将模板追加到目标文本中
    
    fmt.Printf("%q", reg.ExpandString(dst, template, src, match))
    
    // "Say: Hello Golang, Hello World"
    
    }
    
  • func (re *Regexp) LiteralPrefix() (prefix string, complete bool)

    // LiteralPrefix 返回所有匹配项都共同拥有的前缀(去除可变元素)
    
    // prefix:共同拥有的前缀
    
    // complete:如果 prefix 就是正则表达式本身,则返回 true,否则返回 false
    
    func main() {
    
    reg := regexp.MustCompile(`Hello[\w\s]+`)
    
    fmt.Println(reg.LiteralPrefix())
    
    // Hello false
    
    reg = regexp.MustCompile(`Hello`)
    
    fmt.Println(reg.LiteralPrefix())
    
    // Hello true
    
    }
    
  • func (re *Regexp) Longest()

    // 切换到“贪婪模式”
    
    func main() {
    
    text := `Hello World, 123 Go!`
    
    pattern := `(?U)H[\w\s]+o` // 正则标记“非贪婪模式”(?U)
    
    reg := regexp.MustCompile(pattern)
    
    fmt.Printf("%q\n", reg.FindString(text))
    
    // Hello
    
    reg.Longest() // 切换到“贪婪模式”
    
    fmt.Printf("%q\n", reg.FindString(text))
    
    // Hello Wo
    
    }
    
  • func (re *Regexp) Match(b []byte) bool

    // 判断在 b 中能否找到匹配项
    
    func main() {
    
    b := []byte(`Hello World`)
    
    reg := regexp.MustCompile(`Hello\w+`)
    
    fmt.Println(reg.Match(b))
    
    // false
    
    reg = regexp.MustCompile(`Hello[\w\s]+`)
    
    fmt.Println(reg.Match(b))
    
    // true
    
    }
    
  • func (re *Regexp) MatchReader(r io.RuneReader) bool

    // 判断在 r 中能否找到匹配项
    
    func main() {
    
    r := bytes.NewReader([]byte(`Hello World`))
    
    reg := regexp.MustCompile(`Hello\w+`)
    
    fmt.Println(reg.MatchReader(r))
    
    // false
    
    r.Seek(0, 0)
    
    reg = regexp.MustCompile(`Hello[\w\s]+`)
    
    fmt.Println(reg.MatchReader(r))
    
    // true
    
    }
    
  • func (re *Regexp) MatchString(s string) bool

    // 判断在 s 中能否找到匹配项
    
    func main() {
    
    s := `Hello World`
    
    reg := regexp.MustCompile(`Hello\w+`)
    
    fmt.Println(reg.MatchString(s))
    
    // false
    
    reg = regexp.MustCompile(`Hello[\w\s]+`)
    
    fmt.Println(reg.MatchString(s))
    
    // true
    
    }
    
  • func (re *Regexp) NumSubexp() int

    // 统计正则表达式中的分组个数(不包括“非捕获的分组”)
    
    func main() {
    
    reg := regexp.MustCompile(`(?U)(?:Hello)(\s+)(\w+)`)
    
    fmt.Println(reg.NumSubexp())
    
    // 2
    
    }
    
  • func (re *Regexp) ReplaceAll(src, repl []byte) []byte

    // 在 src 中搜索匹配项,并替换为 repl 指定的内容
    
    // 全部替换,并返回替换后的结果
    
    func main() {
    
    b := []byte("Hello World, 123 Go!")
    
    reg := regexp.MustCompile(`(Hell|G)o`)
    
    rep := []byte("${1}ooo")
    
    fmt.Printf("%q\n", reg.ReplaceAll(b, rep))
    
    // "Hellooo World, 123 Gooo!"
    
    }
    
  • func (re *Regexp) ReplaceAllString(src, repl string) string

    // 在 src 中搜索匹配项,并替换为 repl 指定的内容
    
    // 全部替换,并返回替换后的结果
    
    func main() {
    
    s := "Hello World, 123 Go!"
    
    reg := regexp.MustCompile(`(Hell|G)o`)
    
    rep := "${1}ooo"
    
    fmt.Printf("%q\n", reg.ReplaceAllString(s, rep))
    
    // "Hellooo World, 123 Gooo!"
    
    }
    
  • func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte

    // 在 src 中搜索匹配项,并替换为 repl 指定的内容
    
    // 如果 repl 中有“分组引用符”($1、$name),则将“分组引用符”当普通字符处理
    
    // 全部替换,并返回替换后的结果
    
    func main() {
    
    b := []byte("Hello World, 123 Go!")
    
    reg := regexp.MustCompile(`(Hell|G)o`)
    
    rep := []byte("${1}ooo")
    
    fmt.Printf("%q\n", reg.ReplaceAllLiteral(b, rep))
    
    // "${1}ooo World, 123 ${1}ooo!"
    
    }
    
  • func (re *Regexp) ReplaceAllLiteralString(src, repl string) string

    // 在 src 中搜索匹配项,并替换为 repl 指定的内容
    
    // 如果 repl 中有“分组引用符”($1、$name),则将“分组引用符”当普通字符处理
    
    // 全部替换,并返回替换后的结果
    
    func main() {
    
    s := "Hello World, 123 Go!"
    
    reg := regexp.MustCompile(`(Hell|G)o`)
    
    rep := "${1}ooo"
    
    fmt.Printf("%q\n", reg.ReplaceAllLiteralString(s, rep))
    
    // "${1}ooo World, 123 ${1}ooo!"
    
    }
    
  • func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte

    // 在 src 中搜索匹配项,然后将匹配的内容经过 repl 处理后,替换 src 中的匹配项
    
    // 如果 repl 的返回值中有“分组引用符”($1、$name),则将“分组引用符”当普通字符处理
    
    // 全部替换,并返回替换后的结果
    
    func main() {
    
    s := []byte("Hello World!")
    
    reg := regexp.MustCompile("(H)ello")
    
    rep := []byte("$0$1")
    
    fmt.Printf("%s\n", reg.ReplaceAll(s, rep))
    
    // HelloH World!
    
    fmt.Printf("%s\n", reg.ReplaceAllFunc(s,
    
    func(b []byte) []byte {
    
    rst := []byte{}
    
    rst = append(rst, b...)
    
    rst = append(rst, "$1"...)
    
    return rst
    
    }))
    
    // Hello$1 World!
    
    }
    
  • func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string

    // 在 src 中搜索匹配项,然后将匹配的内容经过 repl 处理后,替换 src 中的匹配项
    
    // 如果 repl 的返回值中有“分组引用符”($1、$name),则将“分组引用符”当普通字符处理
    
    // 全部替换,并返回替换后的结果
    
    func main() {
    
    s := "Hello World!"
    
    reg := regexp.MustCompile("(H)ello")
    
    rep := "$0$1"
    
    fmt.Printf("%s\n", reg.ReplaceAllString(s, rep))
    
    // HelloH World!
    
    fmt.Printf("%s\n", reg.ReplaceAllStringFunc(s,
    
    func(b string) string {
    
    return b + "$1"
    
    }))
    
    // Hello$1 World!
    
    }
    
  • func (re *Regexp) Split(s string, n int) []string

    // 在 s 中搜索匹配项,并以匹配项为分割符,将 s 分割成多个子串
    
    // 最多分割出 n 个子串,第 n 个子串不再进行分割
    
    // 如果 n < 0,则分割所有子串
    
    // 返回分割后的子串列表
    
    func main() {
    
    s := "Hello World\tHello\nGolang"
    
    reg := regexp.MustCompile(`\s`)
    
    fmt.Printf("%q\n", reg.Split(s, -1))
    
    // ["Hello" "World" "Hello" "Golang"]
    
    }
    
  • func (re *Regexp) String() string

    // 返回 re 中的“正则表达式”字符串
    
    func main() {
    
    re := regexp.MustCompile("Hello.*$")
    
    fmt.Printf("%s\n", re.String())
    
    // Hello.*$
    
    }
    
  • func (re *Regexp) SubexpNames() []string

    // 返回 re 中的分组名称列表,未命名的分组返回空字符串
    
    // 返回值[0] 为整个正则表达式的名称
    
    // 返回值[1] 是分组 1 的名称
    
    // 返回值[2] 是分组 2 的名称
    
    // ……
    
    func main() {
    
    re := regexp.MustCompile("(?PHello) (World)")
    
    fmt.Printf("%q\n", re.SubexpNames())
    
    //  [""  "Name1"  ""]
    
    }
    

  1. :name: ↩︎

相关文章:

  • 无线传感器网络数据压缩与融合及安全机制的matlab仿真
  • 【C++】红黑树的性质以及实现
  • 软件测试 -- 入门 4 软件测试原则
  • java毕业设计慢性病管理mybatis+源码+调试部署+系统+数据库+lw
  • java毕业设计旅游攻略开发系统mybatis+源码+调试部署+系统+数据库+lw
  • 工具篇 | 07 | maven
  • 数据结构——线性表之顺序表
  • 推荐一下我使用的开发工具
  • 使用C语言实现散列表中的冲突处理方法
  • COBOL--01--基础
  • 实现一个简单的 ctrl+ f 搜索
  • 脱壳工具:BlackDex的使用详解
  • 【数据挖掘】2022年京东算法工程师笔试题(23届)
  • Unet医学细胞分割实战
  • 2022年9月4日:面向初学者的 web 开发--JavaScript 数组和循环(没有完全搞懂)
  • CentOS7 安装JDK
  • Create React App 使用
  • eclipse的离线汉化
  • github指令
  • input实现文字超出省略号功能
  • iOS 系统授权开发
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • MySQL数据库运维之数据恢复
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • React Native移动开发实战-3-实现页面间的数据传递
  • uva 10370 Above Average
  • yii2权限控制rbac之rule详细讲解
  • 笨办法学C 练习34:动态数组
  • 从零开始在ubuntu上搭建node开发环境
  • 多线程 start 和 run 方法到底有什么区别?
  • 飞驰在Mesos的涡轮引擎上
  • 十年未变!安全,谁之责?(下)
  • 使用putty远程连接linux
  • 算法-插入排序
  • 通过几道题目学习二叉搜索树
  • NLPIR智能语义技术让大数据挖掘更简单
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​secrets --- 生成管理密码的安全随机数​
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (过滤器)Filter和(监听器)listener
  • (一)Java算法:二分查找
  • (转)VC++中ondraw在什么时候调用的
  • (转载)PyTorch代码规范最佳实践和样式指南
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试
  • .netcore 获取appsettings
  • .NET分布式缓存Memcached从入门到实战
  • .net开发引用程序集提示没有强名称的解决办法
  • /etc/skel 目录作用
  • /proc/stat文件详解(翻译)
  • ;号自动换行
  • @RequestParam详解