RE模块总结笔记

1.元字符

①方括号 [ ]:指定一个字符类用于存放你需要匹配的字符集合

 [abc] 会匹配字符 a,b 或 c;

 [a-c] 可以实现相同的功能

 [akm$] 会匹配任何字符 'a','k','m' 或 '$','$' 是一个元字符,但在方括号中它不表示特殊含义,它只匹配 '$'字符本身。

 [^5] 会匹配除了 '5' 之外的任何字符

②反斜杠\:如果在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发

例如需要匹配符号 [ 或 \,可以在它们前面加上一个反斜杠,以消除它们的特殊功能:\[,\\。

反斜杠后边跟一些字符还可以表示特殊的意义

其中d:digit,s:space,w:word

它们可以包含在一个字符类中,并且一样拥有特殊含义。例如 [\s,.] 是一个字符类,它将匹配任何空白字符(/s 的特殊含义),',' 或 '.'。

为避免反斜杠冗余的情况,对于原字符串,需要在其前面加上r。

③ * :用于指定前一个字符匹配零次或者多次。

例如 ca*t 将匹配 ct(0 个字符 a),cat(1 个字符 a),caaat(3 个字符 a),等等。

注:正则匹配是贪婪的,在开始时尽可能匹配多的内容,再进行回退。

如 a[bcd]*b匹配abcbd,首先匹配到a,然后在匹配 [bcd]*这一部分时,由于是尽可能多的匹配,会直接匹配到字符串结尾,

再进一步匹配b时,发现不满足,就会回退字符串再次尝试匹配b,这里就是回退到d,匹配不成又回退到b,匹配成功,返回结果。

④ + :用于指定前一个字符匹配一次或者多次。

要特别注意 * 和 + 的区别:* 匹配的是零次或者多次,所以被重复的内容可能压根儿不会出现;+ 至少需要出现一次。例如 ca+t 会匹配 cat 和 caaat,但不会匹配 ct。

⑤ ? :用于指定前一个字符匹配零次或者一次。

⑥ {m,n} :它的含义是前一个字符必须匹配 m 次到 n 次之间。

 {,n} 相当于 {0,n};如果是 {m,} 相当于 {m,+无穷};如果是 {n},则是重复前一个字符 n 次。

⑦ | :

或操作符,对两个正则表达式进行或操作。如果 A 和 B 是正则表达式,A | B 会匹配 A 或 B 中出现的任何字符。为了能够更加合理的工作,| 的优先级非常低。例如 Fish|C 应该匹配 Fish 或 C,而不是匹配 Fis,然后一个 'h' 或 'C'。

⑧ ^ :

匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。
 

re.search('^From', 'From Here to Eternity')

#结果:<_sre.SRE_Match object; span=(0, 4), match='From'>

re.search('^From', 'Reciting From Memory')

#结果:None

⑨ $ :匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。

⑩ \A,\Z:

只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候(即re.M),\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。

⑪\b:单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。

  1. >>> p = re.compile(r'\bclass\b')
  2. >>> print(p.search('no class at all'))  
  3. <_sre.SRE_Match object; span=(3, 8), match='class'>
  4. >>> print(p.search('the declassified algorithm'))
  5. None
  6. >>> print(p.search('one subclass is'))
  7. None

⑫ ():分组符

  1. >> p = re.compile('(a(b)c)d')
  2. >>> m = p.match('abcd')
  3. >>> m.group(0)
  4. 'abcd'
  5. >>> m.group(1)
  6. 'abc'
  7. >>> m.group(2)
  8. 'b'
  9. >>> m.groups()
  10. ('abc', 'b')

⑬ \1,\2...:

\1 表示引用前边成功匹配的序号为 1 的子组。

  1. >>> p = re.compile(r'(\b\w+)\s+\1')
  2. >>> p.search('Paris in the the spring').group()
  3. 'the the'

 

2.方法

注意,由于方法可能会因无结果,后续使用group时可配合try使用,也可以利用if判断是否有匹配对象返回。

使用过程:先进行compile编译,再利用编译后的变量调用函数。

如:

p = re.compile('[a-z]+')

result = p.match("aaa")

结果:

<_sre.SRE_Match object; span=(0, 5), match='aaa'>

返回的是一个匹配对象,而匹配对象还有对应的方法。

如果不使用编译模式,也可以直接使用re的全局函数,如re.match(r'\s+', 'aa aa'),即第一个为正则字符串,第二个为匹配的字符串,当然,这种速度相对较慢。

3.匹配对象

4.re.

①re.X

 这个选项忽略规则表达式中的空白和注释,并允许使用 ’#’ 来引导一个注释。这样可以让你把规则写得更美观些。

rc = re.compile(r"""
# start a rule
/d+
# number
| 
[a-zA-Z]+
# word
""", re.X)
res = rc.match('aaaa')
# print(res)
print(res.group())

②re.I

忽略大小写

③re.S

使得 . 可以匹配任何字符,包括换行符。如果不使用这个标志,. 将匹配除了换行符的所有字符。

a = """sdfkhellolsdlfsdfiooefo:
877898989worldafdsf"""
b = re.findall('hello(.*?)world',a)
c = re.findall('hello(.*?)world',a,re.S)
print ('b is ' , b)
print ('c is ' , c)
 
 
# 输出结果:
# b is  []
# c is  ['lsdlfsdfiooefo:\n877898989']

④re.A

使得 \w,\W,\b,\B,\s 和 \S 只匹配 ASCII 字符,而不匹配完整的 Unicode 字符。这个标志仅对 Unicode 模式有意义,并忽略字节模式。

⑤re.L

LOCALE
使得 \w,\W,\b 和 \B 依赖当前的语言(区域)环境,而不是 Unicode 数据库。

区域设置是 C 语言的一个功能,主要作用是消除不同语言之间的差异。例如你正在处理的是法文文本,你想使用 \w+ 来匹配单词,但是 \w 只是匹配 [A-Za-z] 中的单词,并不会匹配 'é' 或 '&#231;'。如果你的系统正确的设置了法语区域环境,那么 C 语言的函数就会告诉程序 'é' 或 '&#231;' 也应该被认为是一个字符。当编译正则表达式的时候设置了 LOCALE 的标志,\w+ 就可以识别法文了,但速度多少会受到影响。

⑥re.M

通常 ^ 只匹配字符串的开头,而 $ 则匹配字符串的结尾。当这个标志被设置的时候,^ 不仅匹配字符串的开头,还匹配每一行的行首;& 不仅匹配字符串的结尾,还匹配每一行的行尾。

5.group与groups

m = re.search(r"([0-9])*", "123")
print(m.groups())
# 结果:('3',) 原因:[0-9]是一个字符,由于贪婪匹配,会尽可能匹配到最后的3

m = re.search(r"([0-9])*", "123")
print(m.group())
# 结果:123 返回整个匹配的字符串而非括号内的分组

6.非捕获组和命名组

①非捕获组

有时候只是需要用一个组来表示部分正则表达式,并不需要这个组去匹配任何东西,这时可以通过非捕获组来明确表示意图。非捕获组的语法是 (?:...),这个 ... 你可以替换为任何正则表达式。

m = re.search(r"1(?:[abc])+1", "1abc1") #注意养成良好的加r习惯
print(m.group())

②命名组

命名组的语法是 Python 特有的扩展语法:(?P<name>)。很明显,< > 里边的 name 就是命名组的名字啦。命名组除了有一个名字标识之外,跟其他捕获组是一样的。

匹配对象的所有方法不仅可以处理那些由数字引用的捕获组,还可以处理通过字符串引用的命名组。除了使用名字访问,命名组仍然可以使用数字序号进行访问:
 

  1. >>> p = re.compile(r'(?P<word>\b\w+\b)')
  2. >>> m = p.search( '(((( Lots of punctuation )))' )
  3. >>> m.group('word')
  4. 'Lots'
  5. >>> m.group(1)
  6. 'Lots'

7.扩展机制

①前向断言(?=...)

前向肯定断言。如果当前包含的正则表达式(这里以 ... 表示)在当前位置成功匹配,则代表成功,否则失败。一旦该部分正则表达式被匹配引擎尝试过,就不会继续进行匹配了;剩下的模式在此断言开始的地方继续尝试。

②前向否定断言(?!...)

前向否定断言。这跟前向肯定断言相反(不匹配则表示成功,匹配表示失败)。

例如想匹配扩展名不是 bat 的文件,使用.*[.](?!bat$).*$即可

如果正则表达式 bat 在当前位置不匹配,尝试剩下的部分正则表达式;如果 bat 匹配成功,整个正则表达式将会失败(因为是前向否定断言嘛^_^)。(?!bat$) 末尾的 $ 是为了确保可以正常匹配像 sample.batch 这种以 bat 开始的扩展名。

同样,有了前向否定断言,要同时排除 bat 和 exe 扩展名,也变得相当容易:

.*[.](?!bat$|exe$).*$

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值