python正则表达式

re模块

re.sub

Python 的re模块提供了re.sub用于替换字符串中的匹配项。

语法:

re.sub(pattern, repl, string, count=0, flags=0)

参数:

  • pattern : 正则中的模式字符串。
  • repl : 替换的字符串,也可为一个函数。
  • string : 要被查找替换的原始字符串。
  • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
  • flags : 编译时用的匹配模式,数字形式。

实例

#!/usr/bin/python3
import re

phone = "2004-959-559 # 这是一个电话号码"

# 删除注释
num = re.sub(r'#.*$', "", phone)
print ("电话号码 : ", num)

# 移除非数字的内容
num = re.sub(r'\D', "", phone)
print ("电话号码 : ", num)

结果

电话号码 :  2004-959-559 
电话号码 :  2004959559

zip()函数

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。

zip([iterable, ...])
# iterabl -- 一个或多个迭代器;

isinstance()

判断一个对象是否是一个已知的类型

isinstance(object, type)
>>> a = 5
>>> b = 'b'
>>> c = [1,2,3]
>>> d = {'d': 1}
>>> 
>>> isinstance(a, int)
True
>>> isinstance(a, list)
False
>>> isinstance(b, str)
True
>>> isinstance(b, int)
False
>>> isinstance(c, list)
True
>>> isinstance(d, dict)
True

map,el表达式

list(map(lambda el: self.label_map_reverse[el], src))

例子:

from functools import reduce
 
l = ['a', 'bc', 'cde', 'defg']
lf = filter(lambda x: len(x) > 2, l)
 
lm = map(lambda x: x+'_n', l)
 
lr = reduce(lambda x,y: x+y, l)
 
print(list(lf))
 
print(list(lm))
 
print(lr)

输出:

['cde', 'defg']
['a_n', 'bc_n', 'cde_n', 'defg_n']
abccdedefg

map 函数:

map(function, iterable, ...)
  • function – 函数
  • iterable – 一个或多个序列
>>>def square(x) :            # 计算平方数
...     return x ** 2
... 
>>> map(square, [1,2,3,4,5])   # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
 
# 提供了两个列表,对相同位置的列表数据进行相加
>>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]

max()

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import re

reg = re.compile('a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*')
#返回一个字符串里按字母表排序的最长子字符串
def longest(s):
    print reg.findall(s)
#['abcde', 'ap', 'bcdef', '']
    return max(reg.findall(s), key=len)
#加或不加效果相同
print longest('abcdeapbcdef')

Python内置函数max()、min()和sorted()以及列表方法sort()都有一个参数key用来指定排序规则,解决的就是这个问题。

key参数应该是一个可调用对象,在Python中,类、自定义函数、内置函数、lambda表达式、带有特殊方法__call__()的对象都属于可调用函数。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

\d

  • '00\d'可以匹配'007',但无法匹配'00A'
  • '\d\d\d'可以匹配'010'
  • '\w\w\d'可以匹配'py3'

匹配任意字符串

  • 'py.'可以匹配'pyc''pyo''py!'等等。

要匹配变长的字符,在正则表达式中,用*表示任意个字符(包括0个),用+表示至少一个字符,用?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符:

\s

\d{3}\s+\d{3,8}

我们来从左到右解读一下:

  1. \d{3}表示匹配3个数字,例如'010'
  2. \s可以匹配一个空格(也包括Tab等空白符),所以\s+表示至少有一个空格,例如匹配' '' '等;
  3. \d{3,8}表示3-8个数字,例如'1234567'

综合起来,上面的正则表达式可以匹配以任意个空格隔开的带区号的电话号码。

进阶

要做更精确地匹配,可以用[]表示范围,比如:

  • [0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线;
  • [0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串,比如'a100''0_Z''Py3000'等等;
  • [a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量;
  • [a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。

A|B可以匹配A或B,所以(P|p)ython可以匹配'Python'或者'python'

^表示行的开头,^\d表示必须以数字开头。

$表示行的结束,\d$表示必须以数字结束。

你可能注意到了,py也可以匹配'python',但是加上^py$就变成了整行匹配,就只能匹配'py'了。

分组

  • 提取子串
  • ()表示的就是要提取的分组(Group)

^(\d{3})-(\d{3,8})$分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码

>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
>>> m
<_sre.SRE_Match object at 0x1026fb3e8>
>>> m.group(0)
'010-12345'
>>> m.group(1)
'010'
>>> m.group(2)
'12345'

match()和search()区别

match()函数只检测RE是不是在string的开始位置匹配, search()会扫描整个string查找匹配, 也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none

  • match()从开头开始匹配

详见参考网址

案例

import re
# 正则匹配
def find_text(text):
    word_dic = {}
    # m = re.match(u'<ESSAY title')
    reg = re.compile('<ESSAY title')
    # print(re.findall(u"<ESSAY title=\"(.+?)\">", text))
    sen_list = []
    for i in range(len(text)):

        if text[i].startswith("<PASSAGE"):
            sen_list.append(text[i][24:-11])
        elif text[i].startswith("<WRONG>") and text[i+1].startswith("<CORRECTION>"):
            word_dic[text[i][7:-9]] = text[i+1][12:-14]
    # print(sen_list)
    # print(word_dic)
    return sen_list, word_dic

参考网址

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦