第022篇:正则表达式1

什么是正则表达式
  • 用正则符号来描述字符串规则让字符串匹配更简单的一种工具; 正则本身的语法和语言无关,几乎所有的编程语言都支持正则
1、正则符号

1)普通字符:
 在正则表达式中没有特殊功能或者特殊意义的字符都是普通字符
 普通字符在正则表达式中就代表这个符号本身,匹配的时候只能和这个指定的字符进行匹配

2)特殊字符:

.   匹配任意字符(一个点匹配一个字符)
\w  ASCII码表中只能匹配字母、数字、下划线;ASCII码表以外的都可以配(一个\w只能匹配一个字符)
\d  匹配一个数字字符(只能匹配一个数字)
\s  匹配任意一个空白字符

# \W,\D,\S    与小写匹配的字符恰好相反
\W  匹配非数字字母下划线
\D  匹配任意非数字
\S  匹配任意非空字符

代码演示

# .(点)字符:匹配任意字符(一个点匹配一个字符)
re_str = r'a.b'   # 匹配一个长度是3的字符串,第一个字符是a,最后一个字符是b, 中间是任意字符
print(re.fullmatch(re_str, 'abc'))   # None
print(re.fullmatch(re_str, 'a你b'))
print(re.fullmatch(r'a..b', 'au9b'))


# \w字符:ASCII码表中只能匹配字母、数字、下划线;ASCII码表以外的都可以配(一个\w只能匹配一个字符)
re_str = r'a\wb'
print(re.fullmatch(re_str, 'awb'))
print(re.fullmatch(re_str, 'a8b'))
print(re.fullmatch(re_str, 'a_b'))
print(re.fullmatch(re_str, 'a+b'))   # None
print(re.fullmatch(re_str, 'a胡b'))


# \d - 匹配任意一个数字字符
re_str = r'a\d\db'
print(re.fullmatch(re_str, 'a23b'))
print(re.fullmatch(re_str, 'a33b'))
print(re.fullmatch(re_str, 'aa3b'))   # None


# \s - 匹配任意一个空白字符
re_str = r'a\sb'
print(re.fullmatch(re_str, 'a b'))
print(re.fullmatch(re_str, 'a\tb'))
print(re.fullmatch(re_str, 'a\nb'))
print(re.fullmatch(re_str, 'a   b'))   # None


# \W, \D, \S
# \W  匹配非数字字母下划线
# \D  匹配任意非数字
# \S  匹配任意非空字符
print(re.fullmatch(r'a\Db\Sc\Wd', 'aZb=c+d'))
print(re.fullmatch(r'a\Db\Sc\Wd', 'a2b=c+d'))   # None
print(re.fullmatch(r'a\Db\Sc\Wd', 'aZb c+d'))   # None
print(re.fullmatch(r'a\Db\Sc\Wd', 'aZb=c胡d'))   # None

[字符集] - 匹配字符集中的任意一个字符

注意: 一个[]只能匹配一个字符

a. [普通字符集]  例如: [abc] - 匹配a、b、c三个字符中的任意一个
                     [aA123] - 匹配a、A、1、2、3中的任意一个字符
b. [字符1-字符2] 例如:  [1-9]  - 匹配123456789中的任意一个字符
                      [0-9]  - \d
                      [a-z]  - 匹配任意一个小写字母
                      [A-Z]  - 匹配任意一个大写字母
                      [a-zA-Z] - 匹配任意一个字母
                      [\u4e00-\u9fa5]  - 匹配任意一个中文字符
                      [1-9abc] - 匹配1~9或者abc中的任意一个字符
                      [a-zA-Z0-9_]  - 匹配字母数字下划线
                      [\dxyz]  - 任意数字或者x、y、z
注意: 字符1的编码值必须小于字符2的编码值
print(re.fullmatch(r'a[xyz89?]b', 'azb'))
print(re.fullmatch(r'a[xyz]b', 'anb'))
print(re.fullmatch(r'a[23456789]b', r'a7b'))
print(re.fullmatch(r'a[1-9abc]b', 'aab'))
print(re.fullmatch(r'a[abc1-9]b', 'aab'))
print(re.fullmatch(r'a[ac1-9b]b', 'aab'))
print(re.fullmatch(r'a[+*-]b', 'a-b'))
print(re.fullmatch(r'a[\dxyz]b', 'axb'))
print(re.fullmatch(r'a[\\dxyz]b', 'a\\b'))

[^字符集] - 匹配除了字符集以外的任意一个字符

[^abc]  - 匹配除了abc以外的任意一个字符
[^1-9]  - 匹配除了1~9以外的任意一个字符
print(re.fullmatch(r'a[^xyz]b', 'a=b'))   # None
print(re.fullmatch(r'a[xyz^]b', 'a^b'))

2、检测符号
  • \b - 检测是否是单词结尾
单词结尾 - 所有可以区分出两个不同单词的符号都是单词结尾,其中字符串开头和字符串结尾
用法: 检测\b所在的位置是否是单词结尾;不影响匹配的时候的字符串长度
# 匹配一个长度是3的字符串,第一个字符是a,最后一个字符是b,中间是任意一个数字;并且要求b的后面是单词边界
re_str = r'a\db\b'
print(re.fullmatch(re_str, 'a7b'))

re_str = r'a\bxy'
print(re.fullmatch(re_str, 'a xy'))   # None

re_str = r'abc\b\sxyz'
print(re.fullmatch(re_str, 'abc xyz'))

result = re.search(r'\d\d\d\b', 'ashdjfhow2378how 899kah989sf 789')
print(result)
  • ^ - 检测字符串开头
# 判断^所在的位置是否是字符串开头
re_str = r'^\d\d\d'
print(re.fullmatch(re_str, '123'))
print(re.search(re_str, 'k898ahs237khhj'))

# 3)$ - 检测字符串结尾
re_str = r'\d\d\d$'
print(re.search(re_str, '123k898ahs237khhj990'))

re_str = r'^\d\d\d\d\d$'

3、匹配次数

 1) ? + *

  ?  匹配0次或1次
  +  匹配1次或多次
  *  匹配0次或多次
# 1) ?  - 匹配0次或1次
"""
x?   -  x出现0次或1次
\d?  -  任意数字出现0次或1次
[a-z]?  - 小写字母出现0次或1次
"""
re_str = r'ax?b'
print(re.fullmatch(re_str, 'ab'))
print(re.fullmatch(re_str, 'axb'))
print(re.fullmatch(re_str, 'axxb'))   # None

# 2) *  - 匹配0次或多次
re_str = r'a\d*b'   # r'a\d\d...\d\db'
print(re.fullmatch(re_str, 'ab'))
print(re.fullmatch(re_str, 'a2b'))
print(re.fullmatch(re_str, 'a12b'))
print(re.fullmatch(re_str, 'a1272937928329b'))

# 3) +  - 匹配1次或多次
re_str = r'a\d+b'
print(re.fullmatch(re_str, 'ac'))   # None
print(re.fullmatch(re_str, 'a2b'))
print(re.fullmatch(re_str, 'a12b'))
print(re.fullmatch(re_str, 'a1272937928329b'))

 2) {}

{N}  -  匹配N次
{M,N} - 匹配M到N次:  ? -> {0,1}
{M,}  - 匹配至少M次  * -> {0,}   + -> {1,}
{,N}  - 匹配最多N次
re_str = r'a\d{5}b'
print(re.fullmatch(re_str, 'a8867b'))
print(re.fullmatch(re_str, 'a88679b'))
print(re.fullmatch(re_str, 'a8867549b'))


re_str = r'a\d{3,5}b'
print(re.fullmatch(re_str, 'a8867b'))
print(re.fullmatch(re_str, 'a88679b'))
print(re.fullmatch(re_str, 'a8867549b'))


re_str = r'a\d{5,}b'
print(re.fullmatch(re_str, 'a8867b'))
print(re.fullmatch(re_str, 'a88679b'))
print(re.fullmatch(re_str, 'a8867549b'))


re_str = r'a\d{,5}b'
print(re.fullmatch(re_str, 'a8867b'))
print(re.fullmatch(re_str, 'a88679b'))
print(re.fullmatch(re_str, 'a8867549b'))

 3) 贪婪和非贪婪

匹配次数不确定的时候有贪婪和非贪婪两种状态
?、*、+、{M,N}, {M,}, {,N}  -  默认是贪婪的
??, *?, +?, {M,N}?, {M,}?, {,N}?   -  非贪婪

贪婪 - 在能匹配成功的前提下,尽可能多的匹配
非贪婪 - 在能匹配成功的前提下,尽可能少的匹配
re_str = r'\d{3,5}'
re_str1 = r'\d{3,5}?'
print(re.search(re_str, 'abd54378'))
print(re.search(re_str1, 'abd54378'))


re_str = r'\d+'
re_str1 = r'\d+?'
print(re.search(re_str, 'fdj74389028729'))
print(re.search(re_str1, 'fdj74389028729'))



re_str = r'a.+b'
re_str1 = r'a.+?b'
print(re.search(re_str, '==aljfjkl745jbds322nfdjbv'))
print(re.search(re_str1, '==aljfjkl745jbds322nbfdjbv'))
3、分之与分组

1) | - 分之

  • 正则1|正则2 --> 先让正则1去匹配,如果匹配不成功再用正则2匹配;只要两个中有一个能够匹配成功就成功
# 匹配三个数字或者三个字母的字符串
re_str = r'\d{3}|[a-zA-Z]{3}'
print(re.fullmatch(re_str, '890'))

# 匹配一个字符串: abc前是3个数字或者3个字母
# 123abc, uJhabc
re_str = r'\d{3}abc|[a-zA-Z]{3}abc'

2) () - 分组

(正则表达式)  - 将正则表达式看成一个整体进行操作
整体控制次数: ()匹配次数
重复:  带分组的正则表达式\M  --  在\M的位置重前面第M个分组匹配到的内容
# ab78hj90lo23
re_str = r'[a-z]{2}\d{2}[a-z]{2}\d{2}[a-z]{2}\d{2}'

# 9h8k9j8j7h6u5k....
re_str = r'(\d[a-z])+'

# 匹配一个字符串: abc前是3个数字或者3个字母
re_str = r'(\d{3}|[a-z]{3})abc'
print(re.fullmatch(re_str, 'mskabc'))

# abc123abc -成功!  xab234xab  - 成功!  xyz123xyz -成功!
# abc123acb -失败!   xab234sdk  -失败!
# ab-ab   abc-abc   123-123

re_str = r'(\d+)abc\1'
print(re.fullmatch(re_str, '234abc234'))
print(re.fullmatch(re_str, '12345abc12345'))
print(re.fullmatch(re_str, '234abc890'))   # None

re_str = r'(\d+)([a-z]+)=\2'
print(re.fullmatch(re_str, '6kh=kh'))

re_str = r'(\d+)=\1([a-z]+)'
print(re.fullmatch(re_str, '123=123ioo'))

re_str = r'(\d{3})=(\1){2}'
print(re.fullmatch(re_str, '234=234234'))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342