正则表达式


"""
    - 正则表达式
    - 从大量文本中查找规则字符串,比字符串各种查找都快,利用c语言的匹配引擎,广泛用于各种搜索,查找,爬虫
    - 在线工具:
        https://www.regexpal.com/
        http://tool.oschina.net/regex
    

表 1. 正则表达式语法

符号			                意义

.			        表示任意字符,如果说指定了 DOTALL的标识,就表示包括新行在内的所有字符。
^			        表示字符串开头。
$			        表示字符串结尾
*, +, ?	            '*'表示后面可跟 0 个或多个字符,'+'表示后面可跟 1 个或多个字符,'?'表示后面可跟 0 个或多个字符
*?, +?, ??	        在上面的结果中只	取	第一个
{m}			        对于前一个字符重复 m 次
{m,n}		        对于前一个字符重复 m 到 n 次
{m,n}?		        对于前一个字符重复 m 到 n 次,并且取尽可能少的情况
\			        对特殊字符进行转义,或者是指定特殊序列
[]			        表示一个字符集
|			        或者,只匹配其中一个表达式
( … )		        匹配括号中的任意正则表达式
(?#...)		        注释,忽略括号内的内容
(?= … )	            表达式’…’之前的字符串
(?!...)		        后面不跟表达式’…’的字符串
(?<= … )            跟在表达式’…’后面的字符串符合括号之后的正则表达式
(?<!...)	        括号之后的正则表达式不跟在’…’的后面
(?aiLmsux)	        (使用一个或多个字符	'a'	,	'i'	,	'L'	,	'm'	,	's'	,	'u'	,	'x'	.)
                    分别对应这些正则标志符号: re.A (ASCII-onlymatching), re.I (ignorecase),
                    re.L (localedependent),re.M (multi-line), re.S (dot matchesall),
                     re.U (Unicode matching),and re.X (verbose)
(?:...)		        正则括号的非捕获版本. 匹配括号内的任何正则表达式, 
                    但是组里匹配的子字符串在执行了匹配或者被之后的规则引用后将不能被获取
(?imsx-imsx:...)    (使用零个或多个字符'i','m','s','x','-'可选) 表示设置或去除相应的标志符号: 
                    re.I (ignorecase), re.M(multi-line), 
                    re.S (dotmatches all), and re.X (verbose),
                    for the part of the expression.
                    (The flags are described in ModuleContents.)New in version 3.6.
(?P<name>...)		和用括号的正则类似,但是name可以关联匹配到的字符串,作为分组名称
(?P=name)			与上面命名的用法连用,用来代指匹配F到的字符串
(?(id/name)yes	-	如果给定的组id或name存在,就通过
pattern|no-pattern)	yes-pattern去匹配,否则通过no-pattern匹配no-pattern是可选的,可以去掉.

特殊表达式序列			意义

\A			只在字符串开头进行匹配
\b			匹配位于开头或者结尾的空字符串
\B		    匹配不位于开头或者结尾的空字符串
\d			匹配任意十进制数,相当于 [0	-	9]
\D		    匹配任意非数字字符,相当于 [^0-9]
\s		    匹配任意空白字符,相当于 [ \t\n\r\f\v]
\S	        匹配任意非空白字符,相当于 [^ \t\n\r\f\v]
\w		    匹配任意数字和字母,相当于 [a	-	zA	-	Z0	-	9_]
\W	        匹配任意非数字和字母的字符,相当于 [^a-zA-Z0-9_]
\Z			只在字符串结尾进行匹配


"""

re模块使用说明

"""
    1- import re

    2- re.compile()创建一个正则对象regex,一个变量

    多次使用
    regex = re.compile(pattern)# 使用regex对象,推荐,应用更灵活
    result = regex.match(string)
    ==
    match = re.match(pattern, string)# 使用match对象

    3- 使用regex查找一个字符串,返回被匹配的对象

    re.compile(pattern, flags=0)


    把正则表达式的模式和标识转化成正则表达式对象,供 match() 和 search() 这两个函数使用。 re 所定义的 flag 包括:

    re.I 忽略大小写

    re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境 re.M 多行模式

    re.S 即为’ . ’并且包括换行符在内的任意字符(’ . ’不包括换行符) re.X 为了增加可读性,忽略空格和’ # ’后面的注释
    
    e.search(pattern, string, flags=0)

    Scan through string looking for the first location where the regular expression pattern produces a match, and return a corresponding match

    object.

    >>> pattern = re.compile("a")

    >>> pattern.search("abcde")	# Match at index 0

    >>> pattern.search("abcde", 1)	# No match

    re.match(pattern, string, flags=0)

    If zero or more characters at the beginning of string match the regular

    expression pattern, return a corresponding match object.

    Note that even in MULTILINE mode, re.match() will only match at the beginning of the string and not at the beginning of each line.

    If you want to locate a match anywhere in string, use search() instead (see also search() vs. match()).

    分组匹配:

        () 括号分组

        |	管道符号匹配多个分组

        ?	选择出现0次或1次

        re.X	换行,注释

        findall

        -有分组,返回元组列表

        -无分组,返回字符串列表

        split

        - 返回用正则分割后的列表

        案例:

        ip地址

        简单但错误版本:(\d{1,3}\.){3}\d{1,3}

        正确的IP地址:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|

        25[0-5]|[01]?\d\d?)
    
    控制贪心:

        •*? 重复任意次,但尽可能少重复

        •+? 重复1次或更多次,但尽可能少重复

        •?? 重复0次或1次,但尽可能少重复

        •{n,}? 重复n次以上,但尽可能少重复

    内容替换:
        
        new_long_str = re_obj.sub(new_str, old_long_str)

        -添加分组\1\2\3…

        -替换字符串中间空格

        -格式转换

    小案例:

        手机号,电话号:

        手机号码傻瓜版: ^1\d{10}$

        电话号码必备区号版:\d{3}-\d{8}|\d{4}-\d{7}匹配形式如 0511-4405222 或 021-87888822

        邮箱:

        电子邮件的验证:/(\w+@(\w+\.)+\w{2,3})?/

        验证Email地址:^\w+[-+.]\w+)*@\w+([-.]\w+)*\. \w+([-.]\w+)*$

        验证Email地址:/.+@.+\.[a-z]+/


        身份证:

        身份证号: ^(\d{15}|\d{17}(\d|X))$

        -匹配腾讯QQ号:[1-9][0-9]{4,}腾讯QQ号从10000开始

        -只能输入汉字:^[\u4e00-\u9fa5]{1,8}$

        -只能输入由数字和26个英文字母组成的字符串:“^[A-Za-z0-9]+ $”

        -验证用户密码:“^[a-zA-Z]\w{7,17}$”正确格式为:以字母开头,长度在8-18之间, 只能包含字符、数字和下划线。

"""

import re

result = re.search('dongli', 'now  dongli action')  # 匹配1次
print(result)

result = re.match('dongli', 'now dongli action')  # 匹配不到 返回空
print(result)

result = re.match('dongli', 'dongli is good ')  # 匹配开头
print(result)

result = re.search('dongli', 'dongli is good boy').group()  # 匹配到的内弄转成字符串
print(result)

info = 'dongli is good boy'

if re.search('dongli', info):  # 用作条件
    print('找到dongli')
else:
    print('没找到')

info = '130-518-98268'
result = re.search('\d', info)  # 匹配数字
print(result.group())

result = re.search('\d{3}', info).group()  # 匹配多个数字
print(result)

re_num = re.compile('\d+') # 生成匹配对象
result = re_num.findall(info)
result = ''.join(result)
print(result)

re_num1 = re.compile(r'(\d{3})\-(\d{3})\-(\d{5})')  # 分组匹配
result = re_num1.findall(info)
print(result[0][1])
result = re_num1.sub(r'\2\1\3', info)  # 分组替换
print(result)

s = 'dongli is good boy now dongli action hope dongli happy'
re_str = re.compile(r'dongli.+dongli')  # 默认贪心
result = re_str.search(s).group()
print(result)

re_str1 = re.compile(r'dongli.+?dongli')  # 控制贪心
result = re_str1.search(s).group()
print(result)

re_str2 = re.compile(r'\s+')  # 替换空格
result = re_str2.sub('', s)
print(result)

memo_text = '''
1.1 去找小8写个程序
1.2 记一下王总的电话 13912345678
1.3 修改Python程序的bug
1.4 路上买二斤西红柿,遇见卖鸡蛋的就买一斤
1.5 事情太多,忘了今天要干啥
'''

re_date = re.compile(r'(?P<month>\d+)\.(?P<day>\d+)')  # 日期替换
result = re_date.sub(r'\g<month>月\g<day>日', memo_text)
print(result)

最后更新于:2018-06-13 13:16:42