正则表达式

通用正则表达式:

正则表达式:可以用在限制用户输入的范围、长度,也可以在搜寻时给定一个指定的范围和长度。

您正在编写应用程序,并且您希望在用户选择用户名时设置规则。我们希望用户名可以包含字母,数字,下划线和连字符。 为了让它看起来不丑,我们还想限制用户名中的字符数量。

应用场景: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)

  • 27
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值