Python -- 正则表达式(元字符)

正则表达式

动机 : 

1. 处理文本称为计算机主要工作之一
2. 根据文本内容进行固定搜索是文本处理的常见工作
3. 为了快速方便的处理上述问题,正则表达式技术诞生,逐渐发展为一个单独技术被众多语言使用

定义 :

即高级文本匹配模式,提供了搜索,替代等功能,本质是由一些字符和特殊符号组成的字串。这个字串描述了字符和字符的重复行为,可以匹配某一类特征的字符串集合。

目标 : 

1.熟练正则表达式符号和用法
2.能够正确的理解和简单使用正则表达式进行匹配
3.能够使用python  re模块操作正则表达式

正则特点:

* 方便进行检索和修改
* 支持语言众多
* 使用灵活变化多样
* 文本处理,mongo存储某一类型字串,django、tornado路由,爬虫文本匹配

 

正则的规则和用法 

re.findall(regex,string)
功能 : 使用正则表达式匹配字符串
参数 : regex : 正则表达式
        string : 目标字符串
返回值 : 匹配到的内容

一、元字符 (即正则表达式中有特殊含义的字符)

(1)普通字符
元字符 : abc
匹配规则 : 匹配相应的普通字符

findall:在字符串中查找所有匹配成功的组,返回匹配成功的结果列表

In [1]: import re
In [2]: re.findall('ab','abcdeabcde')
Out[2]: ['ab', 'ab']

(2)使用 或 多个正则同时匹配
元字符 : | 
匹配规则:符号两侧的正则均能匹配

In [3]: re.findall('ab|fh','abacfhab')
Out[3]: ['ab', 'fh', 'ab']
In [4]: re.findall('ab | fh','abacfhab')
Out[4]: []

注:|符号两边不能有空格,有则匹配不了

(3)匹配单一字符
元字符 : .
匹配规则: 匹配任意一个字符  '\n'除外

In [5]: re.findall('f.o','affooasand f@o')
Out[5]: ['ffo', 'f@o']

(4)匹配字符串开头
元字符 :  ^   
匹配规则: 匹配一个字符串的开头位置

In [6]: re.findall('^hello','hello world')
Out[6]: ['hello']

(5)匹配字符串结尾
元字符: $
匹配规则: 匹配一个字符串的结尾位置

In [7]: re.findall('py$','hello.py')
Out[7]: ['py']
In [8]: re.findall('py$','python')
Out[8]: []

(6)匹配重复0次或多次
元字符: * 
匹配规则:匹配前面出现的正则表达式 0次或者多次

In [9]: re.findall('ab*','abcdeabasdfabbbbb')
Out[9]: ['ab', 'ab', 'a', 'abbbbb']
In [10]: re.findall('.*py$','hello.py')
Out[10]: ['hello.py']
In [11]: re.findall('.*py','hello.pyc')
Out[11]: ['hello.py']
In [12]: re.findall('.*py$','hello.pyc')
Out[12]: []

(7)匹配重复1次或多次
元字符 : + 
匹配规则: 匹配前面正则表达式至少一次

In [13]: re.findall('ab+','abcdeabasdfabbbbb')
Out[13]: ['ab', 'ab', 'abbbbb']
In [14]: re.findall('.+\.py$','a.py')
Out[14]: ['a.py']

(8)匹配重复0次或1次
元字符: ? 
匹配规则 : 匹配前面出现的正则表达式0次或1次

In [15]: re.findall('ab?','abcdeabasdfabbbbb')
Out[15]: ['ab', 'ab', 'a', 'ab']

(9)匹配重复指定次数
元字符 : {N} 
匹配规则 : 匹配前面的正则表达式N次

In [16]: re.findall('ab{3}','abcdeabasdfabbbbb')
Out[16]: ['abbb']

(10)匹配重复指定次数范围
元字符 : {M,N}
匹配规则 : 匹配前面的正则表达式 m次到n次

In [17]: re.findall('ab{2,5}','abbcdeabbbbasdfabbbbb')
Out[17]: ['abb', 'abbbb', 'abbbbb']

(11)字符集匹配
元字符 : [abcd]
匹配规则 : 匹配中括号中的字符集,或者是字符集区间 的一个字符

字符集不匹配 
元字符 :  [^ abc]
匹配规则 : 匹配出字符集中字符的任意一个字符

In [18]: re.findall('[^abce]','abcdefgh')
Out[18]: ['d', 'f', 'g', 'h']
In [19]: re.findall('[^_0-9a-zA-Z]','740536464@qq.com')
Out[19]: ['@', '.']

(12)匹配任意数字(非数字)字符
元字符 : \d    [0-9]     \D   [^0-9]
匹配规则: \d 匹配任意一个数字字符    \D 匹配任意非数字字符

In [20]: re.findall('1\d{10}','15100317766')
Out[20]: ['15100317766']

(13)匹配任意普通字符(特殊字符)
元字符 : \w  [_0-9a-zA-Z]   \W  [^_0-9a-zA-Z]
匹配规则 : \w 匹配数字字母下划线   \W 除了数字字母下划线

In [22]: re.findall('[A-Z]\w*','Hello World')
Out[22]: ['Hello', 'World']
In [23]: re.findall('\w*-\d*','wangming-56')
Out[23]: ['wangming-56']

(14)匹配任意 (非)空字符
元字符 : \s   \S
匹配规则:  \s  任意空字符  [ \n\0\t\r]  空格 换行  回车 制表
            \S  任意非空字符

In [26]: re.findall('hello\s+\S+','hello lily hello lucy hellokad')
Out[26]: ['hello lily', 'hello lucy']

(15)匹配字符串开头结尾
元字符 : \A  ^    \Z  $
匹配规则: \A 表示匹配字符串开头位置 
           \Z  表示匹配字符串的结尾位置

In [27]: re.findall('\Aabc\Z','abc')
Out[27]: ['abc']
In [28]: re.findall('\Aabc\Z','abcabc')
Out[28]: []

(16)匹配(非)单词边界 
元字符:  \b    \B 
匹配规则  \b  匹配一个单词的边界
          \B  匹配一个单词的非边界
            数字字母下划线和其他字符的交界处认为是单词边界

In [29]: re.findall('is','This is a test')
Out[29]: ['is', 'is']
In [30]: re.findall(r'\bis\b','This is a test')
Out[30]: ['is']

二、贪婪和非贪婪

贪婪模式 : 在使用重复元字符的时候(*  +  ?{m,n}),元字符的匹配总是尽可能多的向后匹配更多内容,即为贪婪模式。贪婪模式是一种默认情况

In [31]: re.findall('ab*','abbbbalkdffab')
Out[31]: ['abbbb', 'a', 'ab']
In [32]: re.findall('ab+','abbbbalkdffab')
Out[32]: ['abbbb', 'ab']
In [33]: re.findall('ab?','abbbbalkdffab')
Out[33]: ['ab', 'a', 'ab']
In [34]: re.findall('ab{3,5}','abbbbalkdffab')
Out[34]: ['abbbb']

非贪婪模式 : 尽可能少的匹配内容,只要满足正则条件即可

In [35]: re.findall('ab{3,5}?','abbbbalkdffab')
Out[35]: ['abbb']
In [36]: re.findall('ab*?','abbbbalkdffab')
Out[36]: ['a', 'a', 'a']
In [37]: re.findall('ab+?','abbbbalkdffab')
Out[37]: ['ab', 'ab']
In [38]: re.findall('ab??','abbbbalkdffab')
Out[38]: ['a', 'a', 'a']
In [39]: re.findall('ab?','abbbbalkdffab')
Out[39]: ['ab', 'a', 'ab']

三、正则表达式的分组

使用()为正则表达式分组
((ab)cd(ef))  : 表示给ab分了一个子组

1. 正则表达式的子组用()表示,增加子组后对整体的匹配没有影响
2. 每个正则表达式可以有多个子组,子组由外到内由左到右为第一第二第三。。。。。。子组
3. 子组表示一个内部整体,很多函数可以单独提取子组的值
4. 子组可以改变 重复行为,将子组作为一个整体重复

match():尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

In [40]: re.match('abcdef','abcdefghigk').group()
Out[40]: 'abcdef'
In [41]: re.match('(ab)cdef','abcdefghigk').group()
Out[41]: 'abcdef'
In [42]: re.match('(ab)cdef','abcdefghigk').group(1)
Out[42]: 'ab'
In [43]: re.match('(ab)*','ababababab').group()
Out[43]: 'ababababab'

命名组和非命名组      格式 : (?P<name>regex)

某些函数可以通过名字提取子组内容,或者通过名字进行键值对的生成。

In [44]: re.match('(?P<word>ab)cdef','abcdefghigk').group()
Out[44]: 'abcdef'

起了名字的子组可以通过名称重复使用

In [45]: re.match('(?P<word>ab)cd(?P=word)','abcdabcdef').group()
Out[45]: 'abcdab'

四、re模块 

1、查看re模块常用的方法和属性

In [1]: import re
In [2]: dir(re)
Out[2]: 
['A',
 'ASCII',
 'DEBUG',
 'DOTALL',
 'I',
 'IGNORECASE',
 'L',
 'LOCALE',
 'M',
 'MULTILINE',
 'S',
 'Scanner',
 'T',
 'TEMPLATE',
 'U',
 'UNICODE',
 'VERBOSE',
 'X',
 '_MAXCACHE',
 '__all__',
 '__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 '__version__',
 '_alphanum_bytes',
 '_alphanum_str',
 '_cache',
 '_cache_repl',
 '_compile',
 '_compile_repl',
 '_expand',
 '_locale',
 '_pattern_type',
 '_pickle',
 '_subx',
 'compile',
 'copyreg',
 'error',
 'escape',
 'findall',
 'finditer',
 'fullmatch',
 'match',
 'purge',
 'search',
 'split',
 'sre_compile',
 'sre_parse',
 'sub',
 'subn',
 'sys',
 'template']

可以通过help查看每一个方法的原型

In [3]: help(re.compile)

compile(pattern, flags=0)
功能 : 获取正则表达式对象
参数 : pattern  正则表达式
        flags  功能标志位 提供正则表达式结果的辅助功能
返回值:返回相应的正则对象

* compile 函数返回值的属性函数 和 re模块属性函数有相同的部分
相同点:
*功能完全相同
不同点:
compile返回值对象属性函数参数中没有pattern和flags部分,因为这两个参数内容在compile生成对象时已经指明,而re模块直接调用这些函数时则需要传入
compile返回值对象属性函数参数中有pos和endpos参数,可以指明匹配目标字符串的起始位置,而re模块直接调用这些函数时是没有这个

In [4]: obj = re.compile('abc')
In [5]: obj.findall('abcdefg')
Out[5]: ['abc']
In [6]: re.findall('abc','abcdefg')
Out[6]: ['abc']
In [7]: dir(obj)
Out[7]: 
['__class__',
 '__copy__',
 '__deepcopy__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__le__',
 '__lt__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'findall',
 'finditer',
 'flags',
 'fullmatch',
 'groupindex',
 'groups',
 'match',
 'pattern',
 'scanner',
 'search',
 'split',
 'sub',
 'subn']
In [11]: obj.findall('abcdefg',pos = 0,endpos = 20)
Out[11]: ['abc']
In [12]: obj.findall('abcdefg',pos = 4,endpos = 20)
Out[12]: []

findall(string,pos ,endpos)
功能 : 将正则表达式匹配到的内容存入一个列表返回
参数 : 要匹配的目标字符串
返回值: 返回匹配到的内容列表
* 如果正则表达式中有子组,则返回子组的匹配内容

import re

pattern = r'\w+'

#获取正则表达式对象
obj = re.compile(pattern)

l = obj.findall('hello world')
print(l)


['hello', 'world']
import re

pattern = r'(ab)cd(ef)'

#获取正则表达式对象
obj = re.compile(pattern)

l = obj.findall('abcdefg')
print(l)


[('ab', 'ef')]
import re

pattern = r'((ab)cd(ef))'

#获取正则表达式对象
obj = re.compile(pattern)

l = obj.findall('abcdefg')
print(l)


[('abcdef', 'ab', 'ef')]

split()
功能: 以正则表达式切割字符串
返回值 : 分割后的内容放入列表

import re

l = re.split(r'\s+','hello python')
print(l)

['hello',python]

sub(pattern,re_string,string,count)
功能:用目标字符串替换正则表达式匹配内容
参数:re_string  用什么来替换
      string    要匹配的目标字符串
      count     最多替换几处
返回值 : 返回替换后的字符串

import re

s = re.sub(r'[A-Z]','##','Hi,Jame. It is a fine day')
print(s)

##i,##ame. ##t is atine day

subn()
功能 : 同sub
参数 : 同sub
返回值 : 比sub多一个实际替换的个数

import re

s = re.sub(r'[A-Z]','##','Hi,Jame. It is a fine day',2)
print(s)

s = re.subn(r'[A-Z]','$$','Hi,Jame. It is a fine day',2)
print(s)

s = re.subn(r'[A-Z]','$$','Hi,Jame. It is a fine day')
print(s)

##i,##ame. It is atine day
('$$i,$$ame. It is atine day', 2)
('$$i,$$ame. It is atine day', 3)

groupindex : compile对象属性 得到捕获组名和第几组数字组成的字典
groups: compile属性,得到一共有多少子组

import re 

pattern = r'((?P<word>ab)c(?P<test>de)f)'
#获取正则表达式对象
obj = re.compile(pattern)

print(obj.groupindex)
print(obj.groups)

{'test': 3, 'word': 2}
3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值