环视匹配只匹配位置,不匹配元素。
只匹配位置,不匹配元素?什么意思呢?
比如:
s = "1abc"
\d可以匹配元素1。而现在我想匹配元素1和元素a之间的位置。这就是环视的作用。
数字书面写法
接下来看个例子:
我们有时会将数字书写成带,号的表达形式。
数字:123456789
书面写法:123,456,789
很明显可以看出在两个位置添加了,号。我们要从一个字符串中找到位置,环视就派上用场了。
现在确定,要实现这个功能就是在找到正确的位置,然后用,号替换。
环视正则表示
先看下环视的正则表达式。
环视的用法很固定,就四种方式:
?= 位置右边匹配...
?<= 位置左边匹配...
?! 位置右边不匹配...
?<! 位置左边不匹配...
程序
知道了上面几点,接下来就是如何确定这个位置了。
数字的书面写法就是从后往前,每三个数字就一个,号,,号不能在第一位。
转换成正则表达式的规则:
匹配某个位置;
这个位置将被,号替换;
这个位置不能在第一位,所以位置前必须有数字;
位置后必须有数字,并且数字的个数是3的倍数,可以是3个、6个、9个等。
程序如下:
def lookahead():
s = '123456789'
pattern = re.compile(r'(?<=\d)(?=(\d{3})+$)') # 结尾符必须当成位置的一部分,因为环视只匹配位置,这个位置不可能是结尾
ns = re.sub(pattern, ',', s) # 匹配位置,不替换元素
print("原始数字:", s)
print("书面数字:", ns)
if __name__ == '__main__':
lookahead()
结果:
原始数字: 123456789
书面数字: 123,456,789
官方实例
官方还有两个例子:
def lh1():
"""匹配的是一个位置(左边是abc)+def"""
m = re.search('(?<=abc)def', 'abcdef')
s = m.group(0)
# 结果匹配的元素就是def
print(s)
def lh2():
"""匹配的是一个位置(左边是-)+egg"""
m = re.search(r'(?<=-)\w+', 'spam-egg')
s = m.group(0)
# 结果匹配的元素就是egg
print(s)
if __name__ == '__main__':
lh1()
lh2()