一. 正则表达式
- 正则表达式:(Regular Expression)
- 正则表达式就正则字符和普通字符组成字符串的规则
正则内容如下
单字符:
. 任意字符(标志s==true时还包括换行符)
[xyz] 字符族
[^xyz] 反向字符族
\d Perl预定义字符族
\D 反向Perl预定义字符族
[:alpha:] ASCII字符族
[:^alpha:] 反向ASCII字符族
\pN Unicode字符族(单字符名),参见unicode包
\PN 反向Unicode字符族(单字符名)
\p{Greek} Unicode字符族(完整字符名)
\P{Greek} 反向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
分组:
(re) 编号的捕获分组
(?P<name>re) 命名并编号的捕获分组
(?:re) 不捕获的分组
(?flags) 设置当前所在分组的标志,不捕获也不匹配
(?flags:re) 设置re段的标志,不捕获的分组
标志的语法为xyz(设置)、-xyz(清楚)、xy-z(设置xy,清楚z),标志如下:
I 大小写敏感(默认关闭)
m ^和$在匹配文本开始和结尾之外,还可以匹配行首和行尾(默认开启)
s 让.可以匹配\n(默认关闭)
U 非贪婪的:交换x*和x*?、x+和x+?……的含义(默认关闭)
边界匹配:
^ 匹配文本开始,标志m为真时,还匹配行首
$ 匹配文本结尾,标志m为真时,还匹配行尾
\A 匹配文本开始
\b 单词边界(一边字符属于\w,另一边为文首、文尾、行首、行尾或属于\W)
\B 非单词边界
\z 匹配文本结尾
转义序列:
\a 响铃符(\007)
\f 换纸符(\014)
\t 水平制表符(\011)
\n 换行符(\012)
\r 回车符(\015)
\v 垂直制表符(\013)
\123 八进制表示的字符码(最多三个数字)
\x7F 十六进制表示的字符码(必须两个数字)
\x{10FFFF} 十六进制表示的字符码
\* 字面值'*'
\Q...\E 反斜线后面的字符的字面值
字符族(预定义字符族之外,方括号内部)的语法:
x 单个字符
A-Z 字符范围(方括号内部才可以用)
\d Perl字符族
[:foo:] ASCII字符族
\pF 单字符名的Unicode字符族
\p{Foo} 完整字符名的Unicode字符族
预定义字符族作为字符族的元素:
[\d] == \d
[^\d] == \D
[\D] == \D
[^\D] == \d
[[:name:]] == [:name:]
[^[:name:]] == [:^name:]
[\p{Name}] == \p{Name}
[^\p{Name}] == \P{Name}
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:] == [\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:] == [0-9A-Fa-f]
常用正则整理如下:
/+特殊字母
: 代表某个取值范围[内容]
:代表一个字符,字符的取值范围就是内部的内容{n,m}
个数,大于等于n小于等于m个.
一个任意内容的字符^
开始$
结束+
至少一个*
任意个?
最多一个
二. Go语言对正则的支持
在regexp包中提供了对正则表达式的支持,并提供了RegExp结构体
可以看出里面有互斥锁,所以在并发下是安全的
// Regexp is the representation of a compiled regular expression.
// A Regexp is safe for concurrent use by multiple goroutines,
// except for configuration methods, such as Longest.
type Regexp struct {
// read-only after Compile
regexpRO
// cache of machines for running regexp
mu sync.Mutex
machine []*machine
}
判断字符串是否与正则匹配最简单的办法是
result,_:=regexp.MatchString(`^\d\w$`,"5A")
fmt.Println(result)
如果需要更多的功能,可以使用Regexp的方式实现,下面列举除了一些常用方法 ```go package main
import ( “regexp” “fmt” )
func main() {
//创建结构体变量
r := regexp.MustCompile(\d[a-zA-Z]
)
//判断是否匹配
fmt.Println(r.MatchString(“5A1”))
/
字符串中满足要求的片段,返回[]string
第二个参数是[]string的长度,-1表示不限制长度
/
fmt.Println(r.FindAllString(“56A6B7C”, -1))
/
把正则表达式匹配的结果当作拆分符,拆分字符串
n > 0 : 返回最多n个子字符串,最后一个子字符串是剩余未进行分割的部分。
n == 0: 返回nil (zero substrings)
n < 0 : 返回所有子字符串
/
fmt.Println(r.Split(“12345qwert”, -1))
//把满足正则要求内容替换成指定字符串
fmt.Println(r.ReplaceAllString(“12345qwert”, “替换了”))
}
<a name="806e2ae7"></a>
# 三.服务器端数据校验
- 数据校验可以有客户端数据校验和服务器端数据校验.双重保证是保证程序安全性的有效措施
- 客户端向服务端发送请求参数,服务器端接收到请求参数后使用正则验证,验证结果通过才能正确执行,例如注册时验证数据格式
- HTML代码如下
```html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
</head>
<body>
<form action="register" method="post">
用户名:<input type="text" name="username"/>用户名必须时6-12位,只能包含字符或数字<br/>
<input type="submit" value="注册"/>
</form>
</body>
</html>
- 服务器代码如下 ```go package main
import ( “net/http” “html/template” “regexp” “fmt” )
func welcome(w http.ResponseWriter, r *http.Request) { t, _ := template.ParseFiles(“view/index.html”) t.Execute(w, nil) }
func register(w http.ResponseWriter, r *http.Request) {
{
u := r.FormValue(“username”)
r, _ := regexp.MatchString(^[0-9a-zA-Z]{6,12}$
, u)
if r {
fmt.Fprintln(w, “注册成功”)
} else {
fmt.Fprintln(w, “用户名格式不正确”)
}
}
}
func main() { server := http.Server{Addr: “:8090”} http.Handle(“/static/“, http.StripPrefix(“/static/“, http.FileServer(http.Dir(“static”)))) http.HandleFunc(“/“, welcome) http.HandleFunc(“/register”, register) server.ListenAndServe() } ```