python-正则(第二部分)

2.1接着上次的第一部分的讲解,下面讲接着讲解特殊字符及其正则的扩展表示法

2.2 进行举例说明


# \d 匹配任何十进制的数字,与[0-9]一致 |\D是与\d是相反的意思
# 在这可使用原始字符串,也可不使用,因其在ASCII中没有相应的字符
m42 = re.search('data\d+.txt', '345ddata456txt.com')
if m42 is not None:
	print(m42.group())
print('--------42--------')
# data456txt

m43 = re.search('data\D+.txt', '345databc.txt.com')
if m43 is not None:
	print(m43.group())
print('--------43---------')
# databc.txt

#\w 匹配任何的字母数字字符,与[A-Za-Z0-9]相同,\W是与\w是相反的意思
m44 = re.search(r'[A-Z]\w+', '123adsdDDD34.sd')
if m44 is not None:
	print(m44.group())
print('--------44---------')
# DDD34

#\s 匹配任何空格字符,与[\n\t\r\v\f]相同,\S是与\s是相反的意思
m45 = re.search(r'of\sthe\sthe1\sthe2\sthe3\s+the4\sthe5',\
				 'of the\nthe1\vthe2\tthe3\r\nthe4\fthe5')
if m45 is not None:
	print(m45.group())
print('--------45--------')
# of the
# the1the2	the3
# 
# the4the5
# \n 换行(换到当前位置的下一行,而不会回到行首)
# \v 纵向制表符
# \t 横向制表符
# \r 回车(回到当前行的行首,而不会换到下一行)
# \f 换页
# 疑问:在这里我们发现了\n与\r都代表了回车换行的作用

# \b匹配单词的边界,在正则的第一部分已讲解过 (\B与之相反)

# \N匹配已保存的子组
m46 = re.search(r'(\d{1,2})/(\d{1,2})/(\d{2}|\d{4})::(\3)/(\2)/(\1)', \
				 '11/20/2002::2002/20/11')
if m46 is not None:
	print(m46.group())
print('--------46--------')
# 11/20/2002::2002/20/11
# 这里的(\3)代表的就是2002对匹配保存的子组进行利用
# 而不是代表(\d{2}|\d{4})

# \c代表的是对转义的字符的本义进行匹配,如匹配\d需使用\\d
m47 = re.search(r'\\d+', '\dddd')
if m47 is not None:
	print(m47.group())
print('--------47--------')
# \dddd

m48 = re.search(r'\d+', '1234')
if m48 is not None:
	print(m48.group())
print('--------48--------')

#\A|\Z 这里的与前面的^|$相同的意思,匹配起始|结束
# 因其有些电脑的键盘上面无^|$,所以这里发明了\A|\Z

#若一个组进行多次匹配,则只能访问最后一个匹配项
m49 = re.search(r'(..)+', 'a1b2c3')
if m49 is not None:
	print(m49.group())
	print(m49.groups())
print('--------49--------')
# a1b2c3
# ('c3', )
# 在这里对一个组进行了多次的匹配,但只保留了最后的一个匹配项

# (?iLmsux)在正则表达式中嵌入一个或多个特殊标记的符号
# (?i):表示 re.I/IGNORECASE,忽略大小写;
# (?L): LOCALE,字符集本地化。
# 这个功能是为了支持多语言版本的字符集使用环境的
# 比如在转义符\w,在英文环境下,它代表[a-zA-Z0-9_],即所以英文字符和数字
# 如果在一个法语环境下使用,缺省设置下,不能匹配"é" 或 "ç",加上这L选项和就可以匹配了
# 不过这个对于中文环境似乎没有什么用,它仍然不能匹配中文字符
# (?m):表示 re.M/MULTILINE,实现多行混合,data数据多行;
# (?s):表示.点符号可以代表任意符号(正常情况.点符号表示除\n之外的任意符号);
# (?u):UNICODE,使用 \w, \W, \b, \B \d \D \s \S这些元字符时将按照UNICODE定义的属性.
# (?x):表示允许用户通过抑制在正则表达式中使用空白符(除了在字符类中或者反斜线转义中)来创建更易读的正则表达式,正则表达式多行;
m50 = re.findall(r'(?i)yes', 'yes Yes YES!')
print(m50)
print('--------50--------')
# ['yes', 'Yes', 'YES']

m51 = re.findall(r'(?i)th\w+', 'The quickest way is through this tunnel')
print(m51)
print('--------51--------')
# ['The', 'through', 'this']

# (?L)这个针对我们中文字符的匹配来说,看起来并没有什么作用
# (?m)让数据可以实现多行混合
m52 = re.findall(r'(?im)^th[\w ]+','''
This line is the first,
another line,
that line, it's the best.
	''')
print(m52)
print('--------52---------')
# ['This line is the first', 'that line']

# (?s) 这部分在正则的第一部分有说明,使之.点号能匹配\n
# (?u) 目前这个的使用案例查找了python官方手册,也未看到举例,待验证
# (?x) 抑制空白字符,便于对正则进行说明
m53 = re.findall(r'''(?x)
	\((\d{3})\) #区号
	[ ]         #空白符
	(\d{3})     #前缀
	-           #横线
	(\d{4})     #终点数字
	''', '(800) 555-1212')
print(m53)
print('-------53--------')
# [('800', '555', '1212')]

m54 = re.findall(r'''(?x)
	\((\d{3})\) #区号
	\  \         #空白符
	(\d{3})     #前缀
	-           #横线
	(\d{4})     #终点数字
	''', '(800)  555-1212')
print(m54)
print('--------54---------')
# [('800', '555', '1212')]
# 空白字符可以用[ ]或者使用\转义字符对空格进行转义

# (?:...)表示匹配不用保存的分组
m55 = re.findall(r'http://(?:\w+\.)*(\w+\.com)', \
				  'http://google.com http://code.gogle.com')
print(m55)
print('--------55--------')
# ['google.com', 'gogle.com']

# (?P<name>...) 由name进行标识而不是数字ID标识的正则分组匹配
# 通常与(?P=name)进行一起使用,(?P=name)匹配之前由(?P<name>)命名的子组
m56 = re.findall(r'''(?x)
	\((?P<areacode>\d{3})\)\s(?P<prefix>\d{3})-(?P<number>\d{4})
	\s #也可以用来匹配空格
	((?P=areacode))-(?P=prefix)-(?P=number)
	[ ]
	1(?P=areacode)(?P=prefix)((?P=number))
	''', '(800) 555-1212 800-555-1212 18005551212')
print(m56)
print('--------56--------')
# [('800', '555', '1212', '800', '1212')]

m57 = re.search(r'''(?x)
	\((?P<areacode>\d{3})\)\s(?P<prefix>\d{3})-(?P<number>\d{4})
	\s #也可以用来匹配空格
	((?P=areacode))-(?P=prefix)-(?P=number)
	[ ]
	1(?P=areacode)(?P=prefix)((?P=number))
	''', '(800) 555-1212 800-555-1212 18005551212')
if m57 is not None:
	print(m57.groupdict())
print('---------57---------')
# {'areacode': '800', 'prefix': '555', 'number': '1212'}
# groupdict匹配对象的方法,返回一个包含所有匹配的命名的子组的字典

# (?#...)注释,就是忽略里面的内容
m58 = re.search(r'\d?(?#\w+)', '01232')
if m58 is not None:
	print(m58.group())
print('--------58--------')
# 0


# (?=...)正向前视断言
m59 = re.findall(r'我们\d+国(2)(?=人)', '我们567国2人的我们789国2人的')
print(m59)
print('--------59--------')
# ['2', '2']

m60 = re.findall(r'我们\d+国2(?=人)', '我们567国2人的我们789国2人的')
print(m60)
print('-------60--------')
# ['我们567国2', '我们789国2']

m61 = re.findall(r'\d+\w+', '876sdf')
print(m61)
print('--------61--------')
# 若没有括号,findall会将整体做为匹配,若有()进行子组匹配,会匹配相应的子组

m62 = re.findall(r'(我们\d+国2)(?=人)的', '我们567国2人的我们789国2人的')
print(m62)
print('--------62--------')
# []
# 证明?=只能放在最后的位置(带有疑问)

m63 = re.findall(r'(我们\d+国2)(?!人)(的)', '我们567国2她们的我们789国2的')
print(m63)
print('--------63--------')
# [('我们789国2', '的')]
# 只要2的后面跟的不是人,然后是的就进行匹配

# (?<=...)是正向后视断言
m64 = re.findall(r'(?<=人)(的)', '我们567国2人的我们789国2人的')
print(m64)
print('-------64-------')
# ['的', '的']
# 好像在(?<=...)的前面不能添加东西,反正会有问题(疑问)

m65 = re.findall(r'(我们\d+国2)(?<!人)(的)', '我们567国2她的我们789国2的')
print(m65)
print('--------65-------')
# [('我们789国2', '的')]

# (?(id|name)Y|N) 若分组的提供的id或者name存在,返回匹配Y,若不存在,返回N
m66 = re.search(r's(\d)?(abc)(?(1)\d|abc)', 'sabcabc')
if m66 is not None:
	print(m66.group())
print('--------66-------')
# sabcabc
# 因其未出现\d,所以匹配's(\d)?abcabc'

m67 = re.search(r's(\d)?(abc)(?(1)\d|abc)', 's2abcabc')
if m67 is not None:
	print(m67.group())
print('--------67-------')
# None
# 因其\d出现了所以是匹配's(\d)?abc\d'

m68 = re.search(r'(\d)+abc(?(1)\d|abc)', 'abcabc')
if m68 is not None:
	print(m68.group())
print('-------68--------')
# None
# 匹配失败相当于是要匹配(\d)+abc\d,因其+决定了必然出现

m69 = re.search(r'(\d)*abc(?(1)\d|abc)', 'abcabc')
if m69 is not None:
	print(m69.group())
print('-------69-------')
# abcabc
# *代表的是0次或者1次,所以上面的情况都可以出现

正则第二部分对常见元字符的匹配,以及扩展表达式的匹配进行了说明,第三部分将对re模块里面的核心函数及其方法进行阐述。详情见正则第三部分。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值