Go如何使用正则表达式
文章目录
正则表达式
正则表达式是一种进行模式匹配和文本操纵的复杂而又强大的工具。虽然正则表达式比纯粹的文本匹配效率低,但是 它却更灵活。按照它的语法规则,随需构造出的匹配模式就能够从原始文本中筛选出几乎任何想你要得到的字符组 合。如果你在Web开发中需要从一些文本数据源中获取数据,那么你只需要按照它的语法规则,随需构造出正确的模式 字符串就能够从原数据源提取出有意义的文本信息。
其实字符串处理我们可以使用strings包来进行搜索(Contains、Index)、替换(Replace)和解析(Split、Join)等操 作,但是这些都是简单的字符串操作,他们的搜索都是大小写敏感,而且固定的字符串,如果我们需要匹配可变的那 种就没办法实现了,当然如果strings包能解决你的问题,那么就尽量使用它来解决。因为他们足够简单、而且性能 和可读性都会比正则好。
本包的正则表达式保证搜索复杂度为O(n),其中n为输入的长度。这一点很多其他开源实现是无法保证的。
RE2语法(Syntax包)
语法
本包采用的正则表达式语法,默认采用perl标志。某些语法可以通过切换解析时的标志来关闭。
单字符:
. 匹配任意一个字符,如果设置 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 匹配x后接着匹配y
x|y 匹配x或y(优先匹配x)
重复:
x* 重复>=0次匹配x,越多越好(优先重复匹配x)
x+ 重复>=1次匹配x,越多越好(优先重复匹配x)
x? 0或1次匹配x,优先1次
x{n,m} n到m次匹配x,越多越好(优先重复匹配x)
x{n,} 重复>=n次匹配x,越多越好(优先重复匹配x)
x{n} 重复n次匹配x
x*? 重复>=0次匹配x,越少越好(优先跳出重复)
x+? 重复>=1次匹配x,越少越好(优先跳出重复)
x?? 0或1次匹配x,优先0次
x{n,m}? n到m次匹配x,越少越好(优先跳出重复)
x{n,}? 重复>=n次匹配x,越少越好(优先跳出重复)
x{n}? 重复n次匹配x
实现的限制:计数格式x{n}等(不包括x*等格式)中n最大值1000。负数或者显式出现的过大的值会导致解析错误,返回ErrInvalidRepeatSize。
分组:
(子表达式) 被捕获的组,该组被编号 (子匹配)
(?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 之间的文本,忽略文本中的正则语法
\\ 匹配字符 \
\^ 匹配字符 ^
\$ 匹配字符 $
\. 匹配字符 .
\* 匹配字符 *
\+ 匹配字符 +
\? 匹配字符 ?
\{ 匹配字符 {
\} 匹配字符 }
\( 匹配字符 (
\) 匹配字符 )
\[ 匹配字符 [
\] 匹配字符 ]
\| 匹配字符 |
“字符类”取值如下(“字符类”包含“Perl类”、“ASCII类”、“Unicode类”):
x 单个字符
A-Z 字符范围(包含首尾字符)
\小写字母 Perl类
[:ASCII类名:] ASCII类
\p{Unicode脚本类名} Unicode类 (脚本类)
\pUnicode普通类名 Unicode类 (普通类)
可以将“命名字符类”作为“字符类”的元素:
[\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 类”之外,其它都一样。
实例
|
|
regexp
regexp的设计原则
regexp包的方法命名规则如下:
Find(All)?(String)?(Submatch)?(Index)?
包含All的方法捕获所有match, 返回值是一个slice. 同时一般会提供一个参数n作为最大匹配次数。
包含String的方法对string类型进行匹配,反之对[]byte进行匹配。
包含Submatch的方法返回所有子匹配,返回值是一个slice. 位置0是对应整个正则表达式匹配结果,位置n(n>0)是第n个子表达式(group) 匹配结果。
包含Index的方法返回匹配的位置。例如,返回loc []int, 则与之对应的匹配字符为src[loc[0]:loc[1]].
判断在 b(s、r)中能否找到 pattern 所匹配的字符串
func Match
func Match(pattern string, b []byte) (matched bool, err error)
匹配检查文本正则表达式是否与字节片匹配。更复杂的用法请使用Compile函数和Regexp对象。
func MatchReader
func MatchReader(pattern string, r io.RuneReader) (matched bool, err error)
MatchReader 检查文本正则表达式是否与 RuneReader 读取的文本匹配。更复杂的用法请使用Compile函数和Regexp对象。
func MatchString
func MatchString(pattern string, s string) (matched bool, err error)
MatchString 检查文本正则表达式是否匹配字符串。更复杂的用法请使用Compile函数和Regexp对象。
|
|
func QuoteMeta
func QuoteMeta(s string) string
QuoteMeta 返回一个字符串,它引用参数文本中的所有正则表达式元字符; 返回的字符串是一个匹配文本文本的正则表达式。例如,QuoteMeta([foo])返回[foo]。
|
|
type Regexp
正则表达式是已编译正则表达式的表示形式。除了配置方法(如Longest)之外,Regexp 可以安全地用于多个 goroutine 的并发使用。
|
|
匹配
func Compile
func Compile(expr string) (*Regexp, error)
编译解析一个正则表达式,并且如果成功返回一个可以用来匹配文本的 Regexp 对象。
当匹配文本时,正则表达式会返回一个尽可能早在输入中开始的匹配(最左边),并在其中选择回溯搜索首先找到的匹配。这种所谓的最左边第一匹配与 Perl,Python 和其他实现使用的语义相同,尽管这个包实现它而没有回溯的代价。对于 POSIX 最左边最长的匹配,请参阅 CompilePOSIX 。
func CompilePOSIX
func CompilePOSIX(expr string) (*Regexp, error)
CompilePOSIX 就像 Compile,但将正则表达式限制为 POSIX ERE(egrep) 语法,并将匹配语义更改为最长。
也就是说,当匹配文本时,正则表达式会返回一个尽可能早在输入中开始的匹配(最左边),并且在它们之间选择尽可能长的匹配。这种所谓的最左边最长匹配与早期正则表达式实现使用和 POSIX 指定的语义相同。
但是,可以有多个最左边最长的匹配,具有不同的匹配选项,并且此包与 POSIX 不同。在可能的最左边最长的匹配中,这个包选择一个回溯搜索首先找到的那个,而 POSIX 指定匹配被选择为最大化第一个子表达的长度,然后第二个等等从左到右。POSIX 规则在计算上是禁止的,甚至没有明确定义。
POSIX 语法不支持 Perl 的语法格式:\d、\D、\s、\S、\w、\W.如果正则表达式语法错误,则返回错误信息。
func MustCompile
func MustCompile(str string) *Regexp
MustCompile 就像compile,但如果表达式不能被解析就会发生panic。它简化了保存已编译正则表达式的全局变量的安全初始化。
func MustCompilePOSIX
func MustCompilePOSIX(str string) *Regexp
MustCompilePOSIX 与 CompilePOSIX 类似,但如果表达式无法解析,则会发生panic。它简化了保存已编译正则表达式的全局变量的安全初始化。
示例:第一匹配和最长匹配
|
|
获取正则表达式信息
func (*Regexp) Longest
func (re *Regexp) Longest()
让正则表达式在之后的搜索中都采用“leftmost-longest”模式。
func (*Regexp) String
func (re *Regexp) String() string
// 返回编译时使用的正则表达式字符串
func (*Regexp) SubexpNames
func (re *Regexp) SubexpNames() []string
SubexpNames 返回此 Regexp 中带括号的子表达式的名称。第一个子表达式的名称是 names1 ,因此如果 m 是匹配片,则 mi 的名称是 SubexpNames()i 。由于整个正则表达式不能被命名,names0 总是空字符串。slice 不应该被修改。
func (*Regexp) LiteralPrefix
func (re *Regexp) LiteralPrefix() (prefix string, complete bool)
LiteralPrefix返回一个字符串字面值prefix,任何匹配本正则表达式的字符串都会以prefix起始。 如果该字符串字面值包含整个正则表达式,返回值complete会设为真。
示例:获取正则表达式信息
|
|
查找:Find、FindSubmatch
func (*Regexp) Find
func (re *Regexp) Find(b []byte) []byte
Find返回保管正则表达式re在b中的最左侧的一个匹配结果的[]byte切片。如果没有匹配到,会返回nil。
func (*Regexp) FindString
func (re *Regexp) FindString(s string) string
Find返回保管正则表达式re在b中的最左侧的一个匹配结果的字符串。如果没有匹配到,会返回"";但如果正则表达式成功匹配了一个空字符串,也会返回""。如果需要区分这种情况,请使用FindStringIndex 或FindStringSubmatch。
re := regexp.MustCompile("fo.?")
fmt.Printf("%q\n", re.FindString("seafood"))
fmt.Printf("%q\n", re.FindString("meat"))
"foo"
""
func (*Regexp) FindSubmatch
func (re *Regexp) FindSubmatch(b []byte) [][]byte
Find返回一个保管正则表达式re在b中的最左侧的一个匹配结果以及(可能有的)分组匹配的结果的[][]byte切片。如果没有匹配到,会返回nil。
func (*Regexp) FindStringSubmatch
func (re *Regexp) FindStringSubmatch(s string) []string
Find返回一个保管正则表达式re在b中的最左侧的一个匹配结果以及(可能有的)分组匹配的结果的[]string切片。如果没有匹配到,会返回nil。
|
|
示例:Find、FindSubmatch
|
|
查找:FindIndex、FindSubmatchIndex
func (*Regexp) FindIndex
func (re *Regexp) FindIndex(b []byte) (loc []int)
Find返回保管正则表达式re在b中的最左侧的一个匹配结果的起止位置的切片(显然len(loc)==2)。匹配结果可以通过起止位置对b做切片操作得到:b[loc[0]:loc[1]]。如果没有匹配到,会返回nil。
func (*Regexp) FindStringIndex
func (re *Regexp) FindStringIndex(s string) (loc []int)
Find返回保管正则表达式re在b中的最左侧的一个匹配结果的起止位置的切片(显然len(loc)==2)。匹配结果可以通过起止位置对b做切片操作得到:b[loc[0]:loc[1]]。如果没有匹配到,会返回nil。
|
|
func (*Regexp) FindReaderIndex
func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int)
Find返回保管正则表达式re在b中的最左侧的一个匹配结果的起止位置的切片(显然len(loc)==2)。匹配结果可以在输入流r的字节偏移量loc[0]到loc[1]-1(包括二者)位置找到。如果没有匹配到,会返回nil。
func (*Regexp) FindSubmatchIndex
func (re *Regexp) FindSubmatchIndex(b []byte) []int
Find返回一个保管正则表达式re在b中的最左侧的一个匹配结果以及(可能有的)分组匹配的结果的起止位置的切片。匹配结果和分组匹配结果可以通过起止位置对b做切片操作得到:b[loc[2n]:loc[2n+1]]。如果没有匹配到,会返回nil。
func (*Regexp) FindStringSubmatchIndex
func (re *Regexp) FindStringSubmatchIndex(s string) []int
Find返回一个保管正则表达式re在b中的最左侧的一个匹配结果以及(可能有的)分组匹配的结果的起止位置的切片。匹配结果和分组匹配结果可以通过起止位置对b做切片操作得到:b[loc[2n]:loc[2n+1]]。如果没有匹配到,会返回nil。
func (*Regexp) FindReaderSubmatchIndex
func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int
Find返回一个保管正则表达式re在b中的最左侧的一个匹配结果以及(可能有的)分组匹配的结果的起止位置的切片。匹配结果和分组匹配结果可以在输入流r的字节偏移量loc[0]到loc[1]-1(包括二者)位置找到。如果没有匹配到,会返回nil。
示例:FindIndex、FindSubmatchIndex
|
|
查找:FindAll、FindAllSubmatch
func (*Regexp) FindAll
func (re *Regexp) FindAll(b []byte, n int) [][]byte
Find返回保管正则表达式re在b中的所有不重叠的匹配结果的[][]byte切片。 n 是查找次数,负数表示不限次数。如果没有匹配到,会返回nil。
func (*Regexp) FindAllString
func (re *Regexp) FindAllString(s string, n int) []string
Find返回保管正则表达式re在b中的所有不重叠的匹配结果的[]string切片。 n 是查找次数,负数表示不限次数。如果没有匹配到,会返回nil。
func (*Regexp) FindAllIndex
func (re *Regexp) FindAllIndex(b []byte, n int) [][]int
Find返回保管正则表达式re在b中的所有不重叠的匹配结果的起止位置的切片。如果没有匹配到,会返回nil。
func (*Regexp) FindAllStringIndex
func (re *Regexp) FindAllStringIndex(s string, n int) [][]int
Find返回保管正则表达式re在b中的所有不重叠的匹配结果的起止位置的切片。如果没有匹配到,会返回nil。
func (*Regexp) FindAllSubmatch
func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte
Find返回一个保管正则表达式re在b中的所有不重叠的匹配结果及其对应的(可能有的)分组匹配的结果的[][][]byte切片。如果没有匹配到,会返回nil。
func (*Regexp) FindAllStringSubmatch
func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string
Find返回一个保管正则表达式re在b中的所有不重叠的匹配结果及其对应的(可能有的)分组匹配的结果的[][]string切片。如果没有匹配到,会返回nil。
示例:FindAll、FindAllSubmatch
|
|
替换
func (*Regexp) ReplaceAll
func (re *Regexp) ReplaceAll(src, repl []byte) []byte
ReplaceAllLiteral返回src的一个拷贝,将src中所有re的匹配结果都替换为repl。在替换时,repl中的’$‘符号会按照Expand方法的规则进行解释和替换,例如$1会被替换为第一个分组匹配结果。
func (*Regexp) ReplaceAllFunc
func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte
ReplaceAllLiteral返回src的一个拷贝,将src中所有re的匹配结果(设为matched)都替换为repl(matched)。repl返回的切片被直接使用,不会使用Expand进行扩展。
func (*Regexp) ReplaceAllLiteral
func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte
ReplaceAllLiteral返回src的一个拷贝,将src中所有re的匹配结果都替换为repl。repl参数被直接使用,不会使用Expand进行扩展。
func (*Regexp) ReplaceAllString
func (re *Regexp) ReplaceAllString(src, repl string) string
ReplaceAllLiteral返回src的一个拷贝,将src中所有re的匹配结果都替换为repl。在替换时,repl中的’$‘符号会按照Expand方法的规则进行解释和替换,例如$1会被替换为第一个分组匹配结果。
|
|
func (*Regexp) ReplaceAllStringFunc
func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string
ReplaceAllLiteral返回src的一个拷贝,将src中所有re的匹配结果(设为matched)都替换为repl(matched)。repl返回的字符串被直接使用,不会使用Expand进行扩展。
func (*Regexp) ReplaceAllLiteralString
func (re *Regexp) ReplaceAllLiteralString(src, repl string) string
ReplaceAllLiteralString返回src的一个拷贝,将src中所有re的匹配结果都替换为repl。repl参数被直接使用,不会使用Expand进行扩展。
|
|
一次替换:Expand
func (*Regexp) Expand
func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte
Expand返回新生成的将template添加到dst后面的切片。在添加时,Expand会将template中的变量替换为从src匹配的结果。match应该是被FindSubmatchIndex返回的匹配结果起止位置索引。(通常就是匹配src,除非你要将匹配得到的位置用于另一个[]byte)
在template参数里,一个变量表示为格式如:$name或${name}的字符串,其中name是长度>0的字母、数字和下划线的序列。一个单纯的数字字符名如$1会作为捕获分组的数字索引;其他的名字对应(?P…)语法产生的命名捕获分组的名字。超出范围的数字索引、索引对应的分组未匹配到文本、正则表达式中未出现的分组名,都会被替换为空切片。
$name格式的变量名,name会尽可能取最长序列:$1x等价于${1x}而非${1}x,$10等价于${10}而非${1}0。因此$name适用在后跟空格/换行等字符的情况,${name}适用所有情况。
如果要在输出中插入一个字面值’$’,在template里可以使用$$。
Expand 要配合 FindSubmatchIndex 一起使用。FindSubmatchIndex 在 src 中进行查找,将结果存入 match 中。这样就可以通过 src 和 match 得到匹配的字符串。
template 是替换内容,可以使用分组引用符 $1、$2、$name 等。Expane 将其中的分组引用符替换为前面匹配到的字符串。然后追加到 dst 的尾部(dst 可以为空)。
说白了 Expand 就是一次替换过程,只不过需要 FindSubmatchIndex 的配合。
func (*Regexp) ExpandString
func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte
ExpandString类似Expand,但template和src参数为字符串。它将替换结果添加到切片并返回切片,以便让调用代码控制内存申请。
示例:Expand
|
|
func (*Regexp) Split
func (re *Regexp) Split(s string, n int) []string
Split将re在s中匹配到的结果作为分隔符将s分割成多个字符串,并返回这些正则匹配结果之间的字符串的切片。
返回的切片不会包含正则匹配的结果,只包含匹配结果之间的片段。当正则表达式re中不含正则元字符时,本方法等价于strings.SplitN。
举例:
s := regexp.MustCompile("a*").Split("abaabaccadaaae", 5)
// s: ["", "b", "b", "c", "cadaaae"]
参数n绝对返回的子字符串的数量:
n > 0 : 返回最多n个子字符串,最后一个子字符串是剩余未进行分割的部分。
n == 0: 返回nil (zero substrings)
n < 0 : 返回所有子字符串
文章作者 Forz
上次更新 2018-11-15