您的位置:首页 > 编程语言 > Python开发

正则表达式(python)

2017-05-14 15:35 190 查看

正则表达式

正则表达式是用来匹配字符串非常强大的工具,在其他编程语言中同样有正则表达式的概念。就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

#导入 re 模块
import re

s = 'nick jenny nice'

# 匹配方式(一)
b = re.match(r'nick',s)
q = b.group()
print(q)

# 匹配方式(二)
# 生成Pattern对象实例,r表示匹配源字符串
a = re.compile(r'nick')
print(type(a))               #<class '_sre.SRE_Pattern'>

b = a.match(s)
print(b)                     #<_sre.SRE_Match object; span=(0, 4), match='nick'>

q = b.group()
print(q)

#被匹配的字符串放在string中
print(b.string)              #nick jenny nice
#要匹配的字符串放在re中
print(b.re)                  #re.compile('nick')


  两种匹配方式区别在于:第一种简写是每次匹配的时候都要进行一次匹配公式的编译,第二种方式是提前对要匹配的格式进行了编译(对匹配公式进行解析),这样再去匹配的时候就不用在编译匹配的格式。

匹配规则:

  .

  "." 匹配任意字符(除了\n)

  \

  "\" 转义字符

  [...]

  "[...]" 匹配字符集

# "." 匹配任意字符(除了\n)
a = re.match(r".","95nick")
b = a.group()
print(b)
输出结果:9

# [...] 匹配字符集
a = re.match(r"[a-zA-Z0-9]","123Nick")
b = a.group()
print(b)
输出结果:1


  

  

  \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]

# \d \D 匹配数字/非数字
a = re.match(r"\D","nick")
b = a.group()
print(b)
输出结果:n

# \s \S 匹配空白/非空白字符
a = re.match(r"\s"," ")
b = a.group()
print(b)
输出结果:

# \w \W 匹配单词字符[a-zA-Z0-9]/非单词字符
a = re.match(r"\w","123Nick")
b = a.group()
print(b)
输出结果:1

a = re.match(r"\W","+-*/")
b = a.group()
print(b)
输出结果:+


  

  *

   "*" 匹配前一个字符0次或者无限次

  +

   "+" 匹配前一个字符1次或者无限次

  ?

   "?" 匹配一个字符0次或者1次
  {m} {m,n}

   {m} {m,n} 匹配前一个字符m次或者m到n次
  *? +? ??

   *? +? ?? 匹配模式变为非贪婪(尽可能少匹配字符串)
# "*" 匹配前一个字符0次或者无限次
a = re.match(r"[A-Z][a-z]*","Aaaaaa123")    #可以只匹配A,123不会匹配上
b = a.group()
print(b)
输出结果:Aaaaaaa

# “+” 匹配前一个字符1次或者无限次
a = re.match(r"[_a-zA-Z]+","nick")
b = a.group()
print(b)
输出结果:nick

# “?” 匹配一个字符0次或者1次
a = re.match(r"[0-8]?[0-9]","95")   #(0-8)没有匹配上9
b = a.group()
print(b)
输出结果:9

# {m} {m,n} 匹配前一个字符m次或者m到n次
a = re.match(r"[\w]{6,10}@qq.com","630571017@qq.com")
b = a.group()
print(b)
输出结果:630571017@qq.com

# *? +? ?? 匹配模式变为非贪婪(尽可能少匹配字符串)
a = re.match(r"[0-9][a-z]*?","9nick")
b = a.group()
print(b)
输出结果:9

a = re.match(r"[0-9][a-z]+?","9nick")
b = a.group()
print(b)
输出结果:9n


  

   ^  

   "^" 匹配字符串开头,多行模式中匹配每一行的开头

   $

   "$" 匹配字符串结尾,多行模式中匹配每一行的末尾

   \A

   \A 仅匹配字符串开头

   \Z   \Z 仅匹配字符串结尾

   \b

   \b 匹配一个单词边界,也就是指单词和空格间的位置
# "^" 匹配字符串开头,多行模式中匹配每一行的开头。
li = "nick\nnjenny\nsuo"
a = re.search("^s.*",li,re.M)
b = a.group()
print(b)
输出结果:suo

# "$" 匹配字符串结尾,多行模式中匹配每一行的末尾。
li = "nick\njenny\nnick"
a = re.search(".*y$",li,re.M)
b = a.group()
print(b)
输出结果:jenny

# \A 仅匹配字符串开头
li = "nickjennyk"
a = re.findall(r"\Anick",li)
print(a)
输出结果:['nick']

# \Z 仅匹配字符串结尾
li = "nickjennyk"
a = re.findall(r"nick\Z",li)
print(a)
输出结果:[]

# \b 匹配一个单词边界,也就是指单词和空格间的位置
a = re.search(r"\bnick\b","jenny nick car")
b = a.group()
print(b)
输出结果:nick


  

  

  |

  "|" 匹配左右任意一个表达式

  ab

  (ab) 括号中表达式作为一个分组

  \<number>

  \<number> 引用编号为num的分组匹配到的字符串

  (?P<key>vlaue)

  (?P<key>vlaue) 匹配到一个字典,去vlaue也可做别名

  (?P=name)

  (?P=name) 引用别名为name的分组匹配字符串

# "|" 匹配左右任意一个表达式
a = re.match(r"nick|jenny","jenny")
b = a.group()
print(b)
输出结果: jenny

# (ab) 括号中表达式作为一个分组
a = re.match(r"[\w]{6,10}@(qq|163).com","630571017@qq.com")
b = a.group()
print(b)
输出结果: 630571017@qq.com

# \<number> 引用编号为num的分组匹配到的字符串
a = re.match(r"<([\w]+>)[\w]+</\1","<book>nick</book>")
b = a.group()
print(b)
输出结果: <book>nick</book>

# (?P<key>vlace) 匹配输出字典
li = 'nick jenny nnnk'
a = re.match("(?P<k1>n)(?P<k2>\w+).*(?P<k3>n\w+)",li)
print(a.groupdict())
输出结果:
{'k2': 'ick', 'k1': 'n', 'k3': 'nk'}

# (?P<name>) 分组起一个别名
# (?P=name) 引用别名为name的分组匹配字符串
a = re.match(r"<(?P<jenny>[\w]+>)[\w]+</(?P=jenny)","<book>nick</book>")
b = a.group()
print(b)
输出结果: <book>nick</book>


  

模块方法介绍:

  match

   从头匹配

  search

  匹配整个字符串,直到找到一个匹配

  findall

  找到匹配,返回所有匹配部分的列表

  finditer

  返回一个迭代器

  sub

  将字符串中匹配正则表达式的部分替换为其他值
  split

  根据匹配分割字符串,返回分割字符串组成的列表
######## 模块方法介绍 #########
# match 从头匹配

# search 匹配整个字符串,直到找到一个匹配

# findall 找到匹配,返回所有匹配部分的列表
# findall 加括号
li = 'nick jenny nick car girl'

r = re.findall('n\w+',li)
print(r)
#输出结果:['nick', 'nny', 'nick']
r = re.findall('(n\w+)',li)
print(r)
#输出结果:['nick', 'nny', 'nick']
r = re.findall('n(\w+)',li)
print(r)
#输出结果:['ick', 'ny', 'ick']
r = re.findall('(n)(\w+)(k)',li)
print(r)
#输出结果:[('n', 'ic', 'k'), ('n', 'ic', 'k')]
r = re.findall('(n)((\w+)(c))(k)',li)
print(r)
#输出结果:[('n', 'ic', 'i', 'c', 'k'), ('n', 'ic', 'i', 'c', 'k')]

# finditer 返回一个迭代器,和findall一样
li = 'nick jenny nnnk'
a = re.finditer(r'n\w+',li)
for i in a:
print(i.group())

# sub 将字符串中匹配正则表达式的部分替换为其他值
li = 'This is 95'
a = re.sub(r"\d+","100",li)
print(a)

li = "nick njenny ncar ngirl"
a = re.compile(r"\bn")
b = a.sub('cool',li,3)      #后边参数替换几次
print(b)

#输出结果:
#coolick cooljenny coolcar ngirl

# split 根据匹配分割字符串,返回分割字符串组成的列表
li = 'nick,suo jenny:nice car'
a = re.split(r":| |,",li)   #或|
print(a)

li = 'nick1jenny2car3girl5'
a = re.compile(r"\d")
b = a.split(li)
print(b)

#输出结果:
#['nick', 'jenny', 'car', 'girl', '']   #注意后边空元素


  

  group()

  返回被 RE 匹配的字符串

  groups()

  返回一个包含正则表达式中所有小组字符串的元组,从 1 到所含的小组号

  groupdict()

  返回(?P<key>vlace)定义的字典

  start()

  返回匹配开始的位置

  end()

  返回匹配结束的位置

  span()

  返回一个元组包含匹配 (开始,结束) 的索引位置

li = 'nick jenny nnnk'

a = re.match("n\w+",li)
print(a.group())

a = re.match("(n)(\w+)",li)
print(a.groups())

a = re.match("(?P<k1>n)(?P<k2>\w+).*(?P<k3>n\w+)",li)
print(a.groupdict())

输出结果:
nick
('n', 'ick')
{'k1': 'n', 'k3': 'nk', 'k2': 'ick'}

-----------------------------------------------
import re
a = "123abc456"
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)   #123abc456,返回整体
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)   #123
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)   #abc
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)   #456

group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3)列出第三个括号匹配部分。


  

  

  re.I

  使匹配对大小写不敏感

  re.L

  做本地化识别(locale-aware)匹配

  re.M

  多行匹配,影响 ^ 和 $

  re.S  

  使 . 匹配包括换行在内的所有字符

  re.U

  根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.

  re.X

  注释,会影响空格(无效了)

#re.I   使匹配对大小写不敏感
a = re.search(r"nick","NIck",re.I)
print(a.group())

#re.L   做本地化识别(locale-aware)匹配
#re.U   根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.

#re.S:.将会匹配换行符,默认.逗号不会匹配换行符
a = re.findall(r".","nick\njenny",re.S)
print(a)
输出结果:
['n', 'i', 'c', 'k', '\n', 'j', 'e', 'n', 'n', 'y']

#re.M:^$标志将会匹配每一行,默认^只会匹配符合正则的第一行;默认$只会匹配符合正则的末行
n = """12 drummers drumming,
11 pipers piping, 10 lords a-leaping"""

p = re.compile("^\d+")
p_multi = re.compile("^\d+",re.M)
print(re.findall(p,n))
print(re.findall(p_multi,n))


  

常见正则列子:

匹配手机号:

# 匹配手机号
phone_num = '13001000000'
a = re.compile(r"^1[\d+]{10}")
b = a.match(phone_num)
print(b.group())


  

匹配IPv4:

# 匹配IP地址
ip = '192.168.1.1'
a = re.compile(r"(((1?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))\.){3}((1?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))$")
b = a.search(ip)
print(b)


  

匹配email:

# 匹配 email
email = '630571017@qq.com'
a = re.compile(r"(.*){0,26}@(\w+){0,20}.(\w+){0,8}")
b = a.search(email)
print(b.group())


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: