通用正则表达式:
正则表达式:可以用在限制用户输入的范围、长度,也可以在搜寻时给定一个指定的范围和长度。
您正在编写应用程序,并且您希望在用户选择用户名时设置规则。我们希望用户名可以包含字母,数字,下划线和连字符。 为了让它看起来不丑,我们还想限制用户名中的字符数量。
应用场景: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<y 表示你最少需要输入x个字符,但最多不能超过y个字符
"[T]?he" => The car is parked in the garage.
{x,} 表示:最少输入x个字符,但无上限的限制
"[0-9]{2,}" => The number was 9.9997 but we rounded it off to 10.0.
{x} 失去了,则表示你只能输入这个恰好的字符数,如:电话号码是11位,这里就可以写[0~9]+{11},表示你只能输入11位数字。
"[0-9]{2}" => The number was 9.9997 but we rounded it off to 10.0.
对字符组()的应用:
字符组要和字符集区分开来(abc)和{abc},括号表示只能匹配到abc连续的,{abc}表示出现abc中一个字符即可,()也可以与|搭配使用表示分支。如:
"(c|g|p)ar" => The car is parked in the garage.
这里出现c或g或p+a+r都可以。
对分支结构“|”的应用:
在正则表达式中垂直条 |
用来定义分支结构,分支结构就像多个表达式之间的条件。现在你可能认为这个字符集和分支结构的工作方式一样。 但是字符集和分支结构巨大的区别是字符集只在字符级别上有作用,然而分支结构在表达式级别上依然可以使用。 例如正则表达式 (T|t)he|car
,表示:匹配大写字母 T
或小写字母 t
,后面跟小写字母 h
,后跟小写字母 e
,或匹配小写字母 c
,后跟小写字母 a
,后跟小写字母 r
。
"(T|t)he|car" => The car is parked in the garage.
分支结构是一种选择,在两种或多种之间满足其中一个即可。 这里显示:The、the、car只要出现都可以。
转义字符\的应用:
{}、[]等我们都被赋予了特殊含义,那我们怎么表示我们要找[]字符呢?加入\即可,如:\[,表示找[字符。
"(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.
在未加^的时候我们选中了the和The,选中后只有The是在文章开头,故只有The被选中
$表示结尾符号:
"(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.
不难看出,如果看前半段The和the都是我们的搜索字段,但后半段表示,前面的the和The后面要跟着fat才被选中,故只有The符合。
负向先行断言
"(T|t)he(?!\sfat)" => The fat cat sat on the mat.
不难看出,如果看前半段The和the都是我们的搜索字段,但后半段表示,前面的the和The后面不跟着fat才被选中,故只有the符合。
正向后行断言:
"(?<=(T|t)he\s)(fat|mat)" => The fat cat sat on the mat.
不难看出,如果看后半段fat和mat都是我们的搜索字段,但前半段表示,fat和mat前面需要跟着The或the才被选中,故两个都符合符合。
负向后行断言:
"(?<!(T|t)he\s)(cat)" => The cat sat on cat.
不难看出,如果看后半段cat和The cat都是我们的搜索字段,但前半段表示,cat前面不能被The或the修饰才被选中,故选择了cat而不是The cat。
总结:
先后行表示断言出现在我要找的目标的前面还是后面,正向表示断言出现了,则那个是我的目标字段,负向表示断言出现了,那么设置的搜索字符不是我们目标字符。
标记:
标记也称为修饰符,因为它会修改正则表达式的输出。这些标志可以以任意顺序或组合使用,并且是正则表达式的一部分。
常见的格式是:/ 中间是我们的内容 /《标记符号》
常用的三种标记。
标记 | 描述 |
---|---|
i | 不区分大小写:将匹配设置为不区分大小写。 |
g | 全局搜索:搜索整个输入字符串中的所有匹配。 |
m | 多行匹配:会匹配输入字符串每一行。 |
不区分大小写:i标记
"The" => The fat cat sat on the mat.
"/The/gi" => The fat cat sat on the mat.
在我们没有使用i标记时,他仅能匹配The,但我们加入i之后他就所有都能匹配了,为什么会加g呢?因为需要全局搜索。如果没有g,他找到第一个The就停下了。
全局搜索:g标记
".(at)" => The fat cat sat on the mat.
"/.(at)/g" => The fat cat sat on the mat.
全局搜索和是全部符合条件的都搜索一遍。
上例中是搜索任意字符+a+t即可。
多行匹配: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})*$
- IPv4 地址:
^((?:(?: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]\/+=%&_\.~?\-]*))*$
- VISA 信用卡号码:
^(4[0-9]{12}(?:[0-9]{3})?)*$
- 日期(MM/DD/YYYY):
^(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}$
- 日期(YYYY/MM/DD):
^(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():
功能: 从字符串开头匹配,返回从开始匹配成功的位置,若从开始未匹配到或不在开始位置匹配到,返回None
原型:match(pattern, string, flags=0)
pattern: 匹配的正则表达式
string: 要匹配的字符串
flags: 标志位,用于控制正则表达式的匹配方式
标志位设置的功能:
- re.I 忽略大小写
- re.L 做本地户识别
- re.M 多行匹配,影响^和$
- re.S 使.匹配包括换行符在内的所有字符
- re.U 根据Unicode字符集解析字符,影响\w,\W,\b,\B
- re.X 使我们以更灵活的格式理解正则表达式
例子:
//搜索代码:
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():
原型:search(pattern, string, flags=0)
功能:扫描整个字符串,并返回第一个成功的匹配
//例子:
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()
原型: findall(pattern, string, flafs=0)
功能: 扫描整个字符串,并返回所有结果的列表
//例子:
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():
原型: finditer(pattern, string, flags=0)
功能: 与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
字符串的替换和修改:
**sub(pattern, repl, string, count=0, flags=0)
subn(pattern, repl, string, count=0, flags=0) **
- pattern: 正则
- repl: 指定的用来替换的字符串
- string: 目标字符串
- count: 最多替换次数,默认为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)
标签:字符,匹配,正则表达式,fat,cat,re,sat
From: https://blog.csdn.net/nwbfygsjdr/article/details/140243093