【golang】正则表达式 查找和替换字符

算法第四版部分章节总结,熟悉正则表达式,需知正则描述模式和正则常用缩略写法。
一、正则描述模式
二、正则缩略写法 (闭包简写,字符集,元字符)
三、正则实践 (字符串查找,字符串替换,网页标签匹配)

正则表示式,就是在一个字符串之中查找满足要求的子字符串

一、正则表达式的描述模式,

连接操作

连接操作就是匹配连接后的结果
有 hello和 go 两个单词将它们连接起来,用正则表式为 (hello)(go),就是连接操作,如果正则有了,但是字符串只有hello是匹配不会成功的,必须满足匹配规则的全部要求

连接操作匹配一个邮箱 (示例:[email protected]

操作 1 2 3 4 5
拆分成 邮箱名 abcabc 小老鼠 @ 服务商域名 qq 点 . 国际域名 com
对应正则 [\w]{5,15} @ [\w]+ . [a-zA-Z]{2,14}

完整的正则 : [\w]{5,15}@[\w]+\.[a-zA-Z]+

连接操作取出网页中的价格 (< div>< span class=“price”> 55.9< /span>< /div>)

操作 1 2 3
拆分 55.9
对应正则 \ [\d\.] \

完整正则 \[\d\.]+\
以上结果会取到这一整个标签,需要把这个匹配结果二次操作,取出其中的价格 [\d\.]+

或操作

或操作就是指定多个匹配结果,
与程序中的 | or 相似,满足其中一个条件就可以了。例如手机号码的匹配,常用号码由13 15 17 18 19 开头,用正则写匹配开头2位 (13|15|17|18|19),或操作用括号包起来,因为这是整个表示式中的其中一个整体,后面的9位[0-9]{9},
连起来就是 (13|15|17|18|19)[0-9]{9}

闭包操作

闭包就是把一个匹配规则重复任意次数,
注册一个用户名,长度可能5位,也可以8位、15位,闭包就可以多次匹配,如[a-z] 默认只匹配一次,匹配结果是a-z中的一个字母,使用闭包操作就是 [a-z]+,那么它将会匹配1次到无数次,因为闭包操作中 + 的匹配字数是至少 1 次。
闭包有以下几种操作, 详细说明见下闭包的简写
? + * {}

但凡涉及到这几个操作符号的 那么就有包含闭包,有 | 号的就是包括或操作,有连接的就是包括连接操作,正则之中这三种操作是重点。

括号

使用括号来改变默认的优先级顺序,与程序中的()是一样一样的,
例如
X(A|B)Z ,匹配的结果 [XAZ, XBZ] ,
*X|A|B|Z,无括号匹配的结果 [X, A, B, Z] *
X|(A|B|Z) ,匹配结果 [XA,XB,XZ],
(X|Y)(A|B)C,匹配结果 [XAC, XBC, YAC, YBC]


二、缩略写法

就像我们力求写出最简洁的程序和高效的算法 一样,避免表达式冗余

字符集

通配符,匹配任意一个字符,中括号内的字符表示匹配其中的任意个,范围集合,指定的范围内的字符,补集即括号内以外的任意字符

名称 记法 示例
通配符 . 匹配除换行符以外的任意字符 abc.,
范围集合 用[]包括,指定某一范围内的值 用 - 来表示 [0-9][0-5][a-z]
指定集合 用[]包括,指定在为某几个值 [aeiou]*
补集 用[]包含,首字符为 ^ [^aeiou]*

闭包的简写

闭包的意思是把一个操作复制任意次数,?号一次或者0次,+号一次或者多次,*号0次或者多次,{}指定次数

闭包以下几种操作,

符号 匹配的字符长度
? 一个或者 0 次
+ 一次或者多次
* 0次或者多次
{n} 指定重复次数等于 n
{n,m} 次数 n 到 m , 示例: {1,5} 1-5次。{2,}至少2次 , {,5}最多5次

转义序列

* ? . + /是正则中的元字符,在它们前面加转义符号\,它们就是没有语义的普通字符
*在正则中是匹配0或无数次,\*则表示一个普通的字符*,
\表示转义 \\则表示一个普通字符\,
还有一些特殊字符, \t制表符,\n换行符, \s空白字符, \d数字

常用元字符

代码 说明
. 匹配除换行符以外的任意字符 除“\n”之外的任何单个字符
\w 匹配字母或数字或下划线 等价于“[A-Za-z0-9_]”。
\s 匹配任意的空白符 等价于 [ \f\n\r\t\v]
\d 匹配数字 等价于[0-9]
\b 匹配单词的开始或结束 单词 never, ne\b可以匹配到ne,
er\b 可以匹配到er,但不能匹配 verb 中的er
^ 匹配字符串的开始
$ 匹配字符串的结束

其它元字符
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。

大写元字符匹配结果与小写元字符相反,示例: \W, \S, \D, \B ,等于 [^\w] ,[\s],[\d],[^\b]

正则表达式, 在编写处理字符串的程序或网页时,经常有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。

正则在线测试: http://tool.chinaz.com/regex/

三、正则实践

go语言正则表达式查找字符串示例

package main 

import(
	"regexp"
	"fmt"
)

func main() {

	text :="Abc a7c MFC 8ca. 你好! Golang/"
	
	//查找连续的小写字母	
	reg := regexp.MustCompile(`[a-z]{2,}`)
	fmt.Printf("%s\n", reg.FindAllString(text, -1))// [bc ca olang]
}

查找连续的非小写字母

	reg = regexp.MustCompile(`[^a-z]{2,}`)
	fmt.Printf("%s\n",reg.FindAllString(text, -1))//[ MFC 8 . 你好! G]

查找连续的单词字母

	reg = regexp.MustCompile(`[a-zA-Z]{2,}`)
	fmt.Printf("%s\n", reg.FindAllString(text, -1))//[Abc MFC ca Golang]

查找连续的非单词字母、非空白字符

	reg = regexp.MustCompile(`[^a-zA-Z\s]+`)
	fmt.Printf("%s\n", reg.FindAllString(text, -1)) //[7 8 . 你好! /]

查找连续的大写字母

	reg = regexp.MustCompile(`[A-Z]+`)
	fmt.Printf("%s\n", reg.FindAllString(text, -1)) //[A MFC G]

查找 abc 或 Golang

	reg = regexp.MustCompile(`(abc|Golang)`)
	fmt.Printf("%s\n", reg.FindAllString(text, -1)) //[Golang]

查找以 G开头,以 / 结尾的单词

	reg = regexp.MustCompile(`G[\w.]*\/`)
	fmt.Printf("%s\n", reg.FindAllString(text, -1)) //[Golang/]

查找从行首开始,以空格结尾的字符串

	reg = regexp.MustCompile(`[\w]+\s`)
	fmt.Printf("%s\n", reg.FindAllString(text, -1)) //[Abc  a7c  MFC ]

查找连续 1 次到 4 次的非空格字符,并以 c 结尾的字符串

	reg = regexp.MustCompile(`[^\s]{1,4}c`)
	fmt.Printf("%s\n", reg.FindAllString(text, -1)) //[Abc a7c 8c]

go语言正则表达式字符串替换示例

package main 

import(
	"regexp"
	"fmt"
)

func main() {

	text :="Abc a7c MFC 8ca. 你好! Golang/"
	
	// 查找 Abc 或 a7c,替换为 Abccc a7ccc
	reg = regexp.MustCompile(`(Ab|a7)c`)
	fmt.Printf("%q\n", reg.ReplaceAllString(text, `${1}ccc`)) //"Abccc a7ccc MFC 8ca. 你好! Golang/"
}

查找 Abc 或 a7c 或 你好 ,替换为**号

	reg = regexp.MustCompile(`(Abc|a7c|你好)`)
	fmt.Printf("%s\n", reg.ReplaceAllString(text, "**"))  //** ** MFC 8ca. **! Golang/

在每个单词后面加上 , 号

	reg = regexp.MustCompile(`([\w.]+)\s`)
	fmt.Printf("%s\n", reg.ReplaceAllString(text, "${1},")) //Abc,a7c,MFC,8ca.,你好! Golang/

把 a 开头的单词 更改成大写 A

	reg = regexp.MustCompile(`[a](\w.)`)
	fmt.Printf("%s\n", reg.ReplaceAllString(text, `A${1}`)) //Abc A7c Aa MFC 8ca. 你好! GolAng/

交换 Abc 和 Golang

	reg = regexp.MustCompile(`(Abc)(.*)(Golang)`)
	fmt.Printf("%s\n", reg.ReplaceAllString(text, `${3}${2}${1}`))  //Golang a7c MFC 8ca. 你好! Abc/

go语言 正则表达式 获取网页标签内的数据 示例

package main 

import(
	"regexp"
	"fmt"
	"io/ioutil"
)

func main() {
	//读取文件
	f,err := ioutil.ReadFile("./spider-page/regexp-1A0001.html")
	if err != nil {
		fmt.Print(err)
	}
	str := string(f)

		//获取 

标题内的文字 reg := regexp.MustCompile(`(?s:(.*?))(.*)`) text := reg.FindAllStringSubmatch(str, -1) fmt.Printf("%s-%s\n",text[0][1],text[0][2]) // 上证指数-1A0001 }

获取今天最低价格

	reg = regexp.MustCompile(`(?s:(.*?))`)
	text = reg.FindAllStringSubmatch(str, -1)
	fmt.Printf("最低价:%s\n",text[0][1]) // 最低价:2533.36

获取今天最高价格

	reg = regexp.MustCompile(`(?s:(.*?))`)
	text = reg.FindAllStringSubmatch(str, -1)
	fmt.Printf("最高价:%s\n",text[0][1]) // 最高价:2554.79

获取当前时间

	reg = regexp.MustCompile(`(?s:(.*?))`)
	text = reg.FindAllStringSubmatch(str, -1)
	fmt.Printf("当前价:%s\n",text[0][1]) // 当前价:2553.83

获取当前价格

	reg = regexp.MustCompile(`

(?s:(.*?))

`) text = reg.FindAllStringSubmatch(str, -1) fmt.Printf("当前时间:%s\n",text[0][1]) // 当前时间:2019年1月12日 15:00:00

返回结果
上证指数-1A0001
最低价:2533.36
最高价:2554.79
当前价:2553.83
当前时间:2019年1月12日 15:00:00

regexp-1A0001.html(示例文件)

上证指数1A0001

2553.83
18.73 0.74%

涨停:0跌停:0

2019年1月12日 15:00:00

  • 今开:2539.55 成交量:149.4亿 振幅:0.85%
  • 最高:2554.79 成交额:1223.8亿 换手:0.45%
  • 最低:2533.36 总市值:276895.2亿 市净率:0
  • 昨收:2535.10 流通市值:238534.6亿 市盈率(动):亏损

你可能感兴趣的:(Go)