正则表达式:可以用在限制用户输入的范围、长度,也可以在搜寻时给定一个指定的范围和长度。
您正在编写应用程序,并且您希望在用户选择用户名时设置规则。我们希望用户名可以包含字母,数字,下划线和连字符。 为了让它看起来不丑,我们还想限制用户名中的字符数量。
应用场景:1、搜索
2、限制用户输入。
功能:1、设置字符长度
2、设置输入的范围。
这一部份就是基于你输入的一个一个匹配,如:
"cat" => The cat sat on the mat
这里的含义是在文段中找到一个为cat的字符串。这里需要注意查询遵从大小写,如这里的cat,就无法匹配CAT、Cat等。
这种最直接、最简单,但一般不适合编写项目,如:我想获取用户合理的qq邮箱,qq邮箱除了尾缀固定为@qq.com,但前面的不可能一致。
元字符 | 描述 |
---|---|
. | 匹配除换行符以外的任意字符。 |
[ ] | 字符类,匹配方括号中包含的任意字符。 |
[^ ] | 否定字符类。匹配方括号中不包含的任意字符 |
* | 匹配前面的子表达式零次或多次 |
+ | 匹配前面的子表达式一次或多次 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。 |
{n,m} | 花括号,匹配前面字符至少 n 次,但是不超过 m 次。 |
(xyz) | 字符组,按照确切的顺序匹配字符 xyz。 |
| | 分支结构,匹配符号之前的字符或后面的字符。 |
\ | 转义符,它可以还原元字符原来的含义,允许你匹配保留字符 [ ] ( ) { } . * + ? ^ $ \ | |
^ | 匹配行的开始 |
$ | 匹配行的结束 |
.号可以匹配除了换行和新行字符的所有字符
本例子中.ar表示任意,找到(任意字符)+a+r即可。
如:
".ar" => The car parked in the garage.
对字符集[]的应用。
字符集和字符组是两个不一样的概念,字符集表示在只要数据是在范围内即可。如:[0~9],表示数字在0到9就符合要求。
下面的例子中,表示:T/t两个选其中一个即可+h+e;
"[Tt]he" => The car parked in the garage.
对否定字符^的应用
^字符的使用,这里有一个注意点这个^要写在[]中,例如:[^0~9],表示除了0和9其他都可以,若写在外面^[0~9]表示开头为0到9,
例子:这里匹配来除了c以外 ,其他字符后续接了ar的字符串。
"[^c]ar" => The car parked in the garage.
这三种修饰都是对前面的符号的修饰,
如:abc?d 这个?修饰c,表示c可有可无,正确匹配时abd和abcd都对。
对*的应用:
*表示可以匹配0次到多次。
下面例子中他会去匹配多次匹配在a-z的字符
"[a-z]*" => The car parked in the garage #21.
还可以和一些转义字符如:\s搭配,\s表示空格,这里表示可以输入0到多次的空格。
"\s*cat\s*" => The fat cat sat on the cat.
这里应该是 cat 和 cat两个部分被框住。
对+号的应用:
+则表示出现一次到多次。如:
"c.+t" => The fat cat sat on the mat.
对比*和+ 我们以上面的例子为例。c.+t 分别搜索下面的几个词语 cat sat caaaat ct. 有两个可以被选中,分别为:cat caaat
若是c.*t则可以有三个可能,分别为:ct、cat、caaat,这里可以看出*只是比+多出了一种可能。
对?的应用:
表示?前面的可有可无。
下面的例子不难看出,只要字符符合he即可,前面有无T只是框不框住的区别。
"[T]?he" => The car is parked in the garage.
{}他起到了设置字符的上下限。实例中日常用户名,一般会让我们输入三个字符,没超过就会被提醒是同一个道理。
{}分为三种情况:
{x,y} 其中x {x,} 表示:最少输入x个字符,但无上限的限制 {x} 失去了,则表示你只能输入这个恰好的字符数,如:电话号码是11位,这里就可以写[0~9]+{11},表示你只能输入11位数字。 字符组要和字符集区分开来(abc)和{abc},括号表示只能匹配到abc连续的,{abc}表示出现abc中一个字符即可,()也可以与|搭配使用表示分支。如: 这里出现c或g或p+a+r都可以。 在正则表达式中垂直条 分支结构是一种选择,在两种或多种之间满足其中一个即可。 这里显示:The、the、car只要出现都可以。 {}、[]等我们都被赋予了特殊含义,那我们怎么表示我们要找[]字符呢?加入\即可,如:\[,表示找[字符。 上例中\.就表示找到.这个符号 ^表示起始符,如一句话 : 在未加^的时候我们选中了the和The,选中后只有The是在文章开头,故只有The被选中 $表示结尾符号: 对比两个例子,不难发现$修饰的符号只会去审核最后的几位符不符合目标。 用\加字符表示一个类型的字符。一般小写表示一个范围。大写表示取反。 正则表达式为常用的字符集和常用的正则表达式提供了简写。简写字符集如下: 断言是什么呢? 他是作为一个判定的范围,出现在查询过程中,但不出现在结果中, 简单的例子,我想找坐在小明前面的小红, 假设班里有两个小明,那么被找到的则是其中一个小明,判断依据是这个小明必须在小红前面。 其中这个小红就是我们的断言,她是我们判断的依据,而不是结果 下面四种断言直接上例子在解析。 不难看出,如果看前半段The和the都是我们的搜索字段,但后半段表示,前面的the和The后面要跟着fat才被选中,故只有The符合。 不难看出,如果看前半段The和the都是我们的搜索字段,但后半段表示,前面的the和The后面不跟着fat才被选中,故只有the符合。 不难看出,如果看后半段fat和mat都是我们的搜索字段,但前半段表示,fat和mat前面需要跟着The或the才被选中,故两个都符合符合。 不难看出,如果看后半段cat和The cat都是我们的搜索字段,但前半段表示,cat前面不能被The或the修饰才被选中,故选择了cat而不是The cat。 先后行表示断言出现在我要找的目标的前面还是后面,正向表示断言出现了,则那个是我的目标字段,负向表示断言出现了,那么设置的搜索字符不是我们目标字符。 标记也称为修饰符,因为它会修改正则表达式的输出。这些标志可以以任意顺序或组合使用,并且是正则表达式的一部分。 常见的格式是:/ 中间是我们的内容 /《标记符号》 常用的三种标记。 在我们没有使用i标记时,他仅能匹配The,但我们加入i之后他就所有都能匹配了,为什么会加g呢?因为需要全局搜索。如果没有g,他找到第一个The就停下了。 全局搜索和是全部符合条件的都搜索一遍。 上例中是搜索任意字符+a+t即可。 功能: 从字符串开头匹配,返回从开始匹配成功的位置,若从开始未匹配到或不在开始位置匹配到,返回None 原型:match(pattern, string, flags=0) 标志位设置的功能: 例子: 原型:search(pattern, string, flags=0) 原型: findall(pattern, string, flafs=0) 本质上是将字符串中按空格为分割依据,进行切割。 原型: finditer(pattern, string, flags=0) //迭代器:相当于里面会存一些匹配的数据,通过循环模式获取。 **sub(pattern, repl, string, count=0, flags=0)"[T]?he" => The car is parked in the garage.
"[0-9]{2,}" => The number was 9.9997 but we rounded it off to 10.0.
"[0-9]{2}" => The number was 9.9997 but we rounded it off to 10.0.
对字符组()的应用:
"(c|g|p)ar" => The car is parked in the garage.
对分支结构“|”的应用:
|
用来定义分支结构,分支结构就像多个表达式之间的条件。现在你可能认为这个字符集和分支结构的工作方式一样。 但是字符集和分支结构巨大的区别是字符集只在字符级别上有作用,然而分支结构在表达式级别上依然可以使用。 例如正则表达式 (T|t)he|car
,表示:匹配大写字母 T
或小写字母 t
,后面跟小写字母 h
,后跟小写字母 e
,或匹配小写字母 c
,后跟小写字母 a
,后跟小写字母 r
。"(T|t)he|car" => The car is parked in the garage.
转义字符\的应用:
"(f|c|m)at\.?" => The fat cat sat on the mat.
定位符的^和$应用:
"(T|t)he" => The car is parked in the garage.
"^(T|t)he" => The car is parked in the garage.
"(at\.)" => The fat cat. sat. on the mat.
"(at\.)$" => The fat cat sat on the mat.
简写字符集:
简写
描述
.
匹配除换行符以外的任意字符
\w
匹配所有字母和数字的字符:
[a-zA-Z0-9_]
\W
匹配非字母和数字的字符:
[^\w]
\d
匹配数字:
[0-9]
\D
匹配非数字:
[^\d]
\s
匹配空格符:
[\t\n\f\r\p{Z}]
\S
匹配非空格符:
[^\s]
断言:断言分四种。
符号
描述
?=
正向先行断言
?!
负向先行断言
?<=
正向后行断言
?
负向后行断言
正向先行断言:
"(T|t)he(?=\sfat)" => The fat cat sat on the mat.
负向先行断言
"(T|t)he(?!\sfat)" => The fat cat sat on the mat.
正向后行断言:
"(?<=(T|t)he\s)(fat|mat)" => The fat cat sat on the mat.
负向后行断言:
"(? The cat sat on cat.
总结:
标记:
标记
描述
i
不区分大小写:将匹配设置为不区分大小写。
g
全局搜索:搜索整个输入字符串中的所有匹配。
m
多行匹配:会匹配输入字符串每一行。
不区分大小写:i标记
"The" => The fat cat sat on the mat.
"/The/gi" => The fat cat sat on the mat.
全局搜索:g标记
".(at)" => The fat cat sat on the mat.
"/.(at)/g" => The fat cat sat on the mat.
多行匹配:m标记:
m
修饰符被用来执行多行的匹配。正如我们前面讨论过的 (^, $)
,使用定位符来检查匹配字符是输入字符串开始或者结束。但是我们希望每一行都使用定位符,所以我们就使用 m
修饰符。 例如正则表达式 /at(.)?$/gm
,表示:小写字母 a
,后跟小写字母 t
,匹配除了换行符以外任意字符零次或一次。而且因为 m
标记,现在正则表达式引擎匹配字符串中每一行的末尾。"/.at(.)?$/gm" => The fat
cat sat
on the mat.
常用正则表达式:可以将这些作为练习进行总结。
^\d+$
^-\d+$
^+?[\d\s]{3,}$
^+?[\d\s]+(?[\d\s]{10,}$
^-?\d+$
^[\w\d_.]{4,16}$
^[a-zA-Z0-9]*$
^[a-zA-Z0-9 ]*$
^(?=^.{6,}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$
^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4})*$
^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))*$
^([a-z])*$
^([A-Z])*$
^(((http|https|ftp):\/\/)?([[a-zA-Z0-9]\-\.])+(\.)([[a-zA-Z0-9]]){2,4}([[a-zA-Z0-9]\/+=%&_\.~?\-]*))*$
^(4[0-9]{12}(?:[0-9]{3})?)*$
^(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}$
^(19|20)?[0-9]{2}[- /.](0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])$
^(5[1-5][0-9]{14})*$
python中使用正则表达式:
1、使用前导入import re包。
正则表达式的规则和上面的一样。
re.match():
pattern: 匹配的正则表达式
string: 要匹配的字符串
flags: 标志位,用于控制正则表达式的匹配方式
//搜索代码:
import re
addr = "Www.baidu.com"
re.match("www", addr, re.I) //www表示要搜索的东西,addr被赋予了Www.baidu.com ,re.I表示忽略大小写。
//结果:
<_sre.SRE_Match object; span=(0, 3), match='Www'>
re.search():
功能:扫描整个字符串,并返回第一个成功的匹配//例子:
import re
addr = "www.baidu.com"
print(re.match("bai", addr))
print(re.search("bai", addr))
//结果:
None
<_sre.SRE_Match object; span=(4, 7), match='bai'>
//这里可以看出区别,search不需要考虑是开头还是结尾的问题,找到即可返回答案。
re.findall()
功能: 扫描整个字符串,并返回所有结果的列表//例子:
import re
addr = "www.baidu.com"
print(re.findall("w", addr))
//结果:
['w', 'w', 'w']
//本例返回的是所有符合的结果,和全局搜索g很像。
字符串切割:
//例子:
import re
str1 = 'wang is a good man'
print(str1.split())
print(str1.split(" "))
print(re.split(r" +", str1))
//结果:
['wang', 'is', 'a', 'good', 'man']
['wang', '', '', '', 'is', 'a', 'good', 'man']
['wang', 'is', 'a', 'good', 'man']
re.finditer():
功能: 与findall类似,扫描整个字符串,但返回的是一个迭代器//例子:
import re
strs = "wang is a good man! wang is a nice man! wang is a very handsome man!"
d = re.finditer(r"wang", strs) //将搜索到的符合的字符存入迭代器中,被赋值于d中
for i in d: //i会顺序的去d中读取数据。
print(i.group())
//结果:
wang
wang
wang
字符串的替换和修改:
subn(pattern, repl, string, count=0, flags=0) **
//例子:
import re
str2 = "wang is a good good good boy"
print(re.sub("good", "nice", str2))
print(re.subn("good", "nice", str2, count=2))
//结果:
wang is a nice nice nice boy
('wang is a nice nice good boy', 2)