正则表达式

 

正则表达式为高级的文本模式匹配、抽取、与/或文本形式的搜索和替换功能提供了基础。简单的说,正则表达式是一些由字符和特殊符号组成的字符串,他们描述了模式的重复或者表述多个字符,于是正则表达式能按照某种模式匹配一系列有相似特征的字符串。换句话说,他们能够匹配多个字符串,一种只能匹配一个字符串的正则表达式模式是很乏味并且毫无作用的。

主要分为两部分:

  1.正则表达式

  2.python中的re模块

 

所有关于正则表达式的操作都使用 python 标准库中的 re 模块。

 

 

我们的第一个正则表达式

1 import re
2 
3 pattern = re.compile(r'Python')#进行预编译
4 m = re.search(pattern,'Hello Python')
5 
6 print(m.group())

>>>Python
1 import re
2 
3 m = re.search(r'Python','Hello Python')
4 
5 print(m.group())
#没有预编译,结果也是相同的
>>>Python

1.pattern = re.compile(r'Python')

 将正则表达式进行预编译,也可以不编译直接进行匹配,但是在代码执行过程中,解释器都会将正则表达式模式编译成正则表达式对象,而且正则表达式在执行过程中将进行多次比较操作,因此强烈建议使用预编译。

2.r'Python'

 一个形式最简单的正则表达式,匹配字符串中的Python。

 python中字符串前面加 r   表示原生字符串

spark 正则表达式 正则表达式 py_Python

spark 正则表达式 正则表达式 py_spark 正则表达式_02

与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"表示。同样,匹配一个数字的"\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

原生字符串

 正则表达式的表达方式还有很多,一会儿会做说明,更详细的还请查阅相关文档。

3.re.search(r'Python','Hello Python')

 调用 python 中 re 模块的 search() 方法,第一个参数是正则表达式,第二个参数是要进行匹配的字符串,返回一个匹配对象

 re 模块中还有很多方法,下面也会做介绍。

4.m.group()

 m就是匹配对象,所以如果直接print(m),会输出一个对象,并不能得到我们想看到的匹配结果。

 匹配对象有两个主要的方法:group()和groups(),我们用这两个方法来得到我们想要的结果。具体用法后面会详细讲解。

下面进入到正式的正则表达式学习中

接下来会将我们上面第一个正则表达式中的知识点进行详细讲解,如果在接下来的学习中感到困惑,试着将相关内容替换到上面的代码中理解。

一、正则表达式

1.普通字符描述


 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用象 ‘[.\n]‘ 的模式。

x|y

匹配 x 或 y。例如,’z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。

[xyz]  

字符集合。匹配所包含的任意一个字符。例如, ‘[abc]‘ 可以匹配 “plain” 中的 ‘a’。

[^xyz]

负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]‘ 可以匹配 “plain” 中的’p','l','i','n'。

[a-z] 

字符范围。匹配指定范围内的任意字符。例如,’[a-z]‘ 可以匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符。

[^a-z]

负值字符范围。匹配任何不在指定范围内的任意字符。例如,’[^a-z]‘ 可以匹配任何不在 ‘a’ 到 ‘z’ 范围内的任意字符。

\d  

匹配一个数字字符。等价于 [0-9]。

\D 

匹配一个非数字字符。等价于 [^0-9]。

\w 

匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]‘。

\W

 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]‘。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.特殊字符描述

$

 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 \$。

( )

标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。

*

匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。

+

匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。

.

匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 \。


 标记一个中括号表达式的开始。要匹配 [,请使用 \[。

?

匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。


将下一个字符标记为或特殊字符、或原义字符、或后向引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\' 匹配 "\",而 '\(' 则匹配 "("。

^

匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用\^。

{

标记限定符表达式的开始。要匹配 {,请使用 \{。


指明两项之间的一个选择。要匹配 |,请使用 \|。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.非打印字符

 \f

 匹配一个换页符。等价于 \x0c 和 \cL。

 \n

 匹配一个换行符。等价于 x0a 和 cJ。

 \r

 匹配一个回车符。等价于 x0d 和 cM。

 \s

 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [?\f\n\r\t\v]。

 \S

 匹配任何非空白字符。等价于 [^?\f\n\r\t\v]。

 \t 

 匹配一个制表符。等价于 \x09 和 \cI。

 \v

 匹配一个垂直制表符。等价于 \x0b 和 \cK。

 

 

 

 

 

 

 

 

 

 

 

4.限定符


匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。 * 等价于{0,}。

+

匹配前面的子表达式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。

?

匹配前面的子表达式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等价于 {0,1}。

{n}

n 是一个非负整数。匹配确定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。

{n,}

n 是一个非负整数。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o*’。

{n,m}

m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。刘, “o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。

 

 

 

 

 

 

 

 

 

 

看了这么多,我们来上一些实例看看:

spark 正则表达式 正则表达式 py_Python

spark 正则表达式 正则表达式 py_spark 正则表达式_02

m = re.search(r'(p|t)h','the')
print(m.group())
#>>>th
m = re.search(r'[abcde]','the')#匹配字符集中任意字符
print(m.group())
#>>>e
m = re.search(r'..','the')#  . 匹配任意字符(不包括\n)
print(m.group())
#>>>th
m = re.search(r'^ind(e|a)','inda inde')#匹配字符串起始部分
print(m.group())
#>>>inda
m = re.search(r'ind(e|a)$','inda inde')#匹配字符串终止部分
print(m.group())
#>>>inde
m = re.search(r'inde*','indeeeee')#匹配0次或多次前面出现的正则表达式
print(m.group())
#>>>indeeeee
m = re.search(r'inde{3}','indeeeee')#匹配n次前面出现的正则表达式
print(m.group())
#>>>indeee
m = re.search(r'inde*?','indeeeee')# 非贪婪匹配
print(m.group())
#>>>ind
m = re.search(r'inde+?','indeeeee')# 非贪婪匹配
print(m.group())
#>>>inde
m = re.search(r'i(nd)e*','indeeeee')# ()用于分组,配合group()方法使用
print(m.group(0),m.group(1))
#>>>indeeeee nd

示例

 二、正则表达式和python语言

1.match()方法

  从字符串的起始部分对模式进行匹配,如果匹配成功,就返回一个匹配对象,如果匹配失败,就返回None

2.search()方法

  在字符串中搜索出模式第一次出现的匹配情况,如果成功就返回匹配对象,失败返回None

3.findall()和finditer()查找每一次出现的位置

  查找模式在字符串中出现的所有位置,与search()和match()不同的是findall()总是返回一个列表,匹配失败返回一个空列表,匹配成功,列表将包含所有成功的匹配部分。

  finditer()与findall()的区别在于返回的是一个迭代器还是一个列表。更节省内存。

4.sub()和subn()搜索与替换

  两者几乎一样,都是将某字符串中所有匹配正则表达式的部分进行某种形式的替换。

  不同的是返回的值,sub()返回替换后的字符串,subn()返回替换后的字符串和表示替换总数的数字,一起作为一个拥有两个元素的元组返回

5.split()分割字符串

  re.split()与str.split()的工作方式相同,可以通过为参数max设定一个值来指定最大分割数

spark 正则表达式 正则表达式 py_Python

spark 正则表达式 正则表达式 py_spark 正则表达式_02

m = re.match(r'foo','food on the table')
if m is not None:
    print(m.group())
#>>>foo

m = re.search(r'foo','seafood')
if m is not None:
    print(m.group())
#>>>foo

m = re.findall(r'th\w+','This and that.')
print(m)
#>>>['that']
m = re.findall(r'th\w+','This and that.',re.I)#不区分大小写
print(m)
#>>>['This','that']
m = re.finditer(r'th\w+','This and that.',re.I)
for i in m:
    print(i.group())
#>>>This
#>>>that

m = re.sub(r'[ae]','X','abcdef')
print(m)
#>>>XbcdXf
m = re.subn(r'[ae]','X','abcdef')
print(m)
#>>>('XbcdXf', 2)

m = re.split(':','str1:str2:str3')
print(m)
#>>>['str1', 'str2', 'str3']

示例

6.group()和groups()方法

  匹配成功后返回的匹配对象拥有两个方法,group()和groups()。

  group()要么返回整个匹配对象,要么根据要求返回特定子组。groups()则返回一个包含唯一或者全部子组的元组。如果没有子组的要求,group()任然返回整个匹配,groups()则返回一个空元组。

spark 正则表达式 正则表达式 py_Python

spark 正则表达式 正则表达式 py_spark 正则表达式_02

m = re.match(r'(\w\w\w)-(\d\d\d)','abc-123')
print(m.group())
#>>>abc-123
print(m.group(1))
#>>>abc
print(m.group(2))
#>>>123
print(m.groups())
#>>>('abc', '123')

示例

 7.常用正则表达式

  1. 手机:/^0?1[3|4|5|8][0-9]\d{8}$/
  2. 固话:/^0[\d]{2,3}-[\d]{7,8}$/
  3. 电子邮箱:/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/
    /^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/
  4. 用户名:/^[a-z0-9_-]{3,16}$/
  5. 密码:/^[a-z0-9_-]{6,18}$/
  6. URL:/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/