正则表达式

JavaScript RegExp 对象

直接量语法

/pattern/attributes	
new RegExp(pattern, attributes);

var str="Every man in the world! Every woman on earth!";
patt=/man/g;
str2=str.replace(patt,"person");
# Every person in the world! Every woperson on earth! 修饰符

i	执行对大小写不敏感的匹配。
g	执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m	执行多行匹配。

方括号用于查找某个范围内的字符:

[abc]	查找方括号之间的任何字符。
[^abc]	查找任何不在方括号之间的字符。
[0-9]	查找任何从 0 至 9 的数字。
[a-z]	查找任何从小写 a 到小写 z 的字符。
[A-Z]	查找任何从大写 A 到大写 Z 的字符。
[A-z]	查找任何从大写 A 到小写 z 的字符。
[adgk]	查找给定集合内的任何字符。
[^adgk]	查找给定集合外的任何字符。
(red|blue|green)	查找任何指定的选项。

元字符(Metacharacter)是拥有特殊含义的字符:

.	查找单个字符,除了换行和行结束符。
\w	查找单词字符。
\W	查找非单词字符。
\d	查找数字。
\D	查找非数字字符。
\s	查找空白字符。
\S	查找非空白字符。
\b	匹配单词边界。
\B	匹配非单词边界。
\0	查找 NUL 字符。
\n	查找换行符。
\f	查找换页符。
\r	查找回车符。
\t	查找制表符。
\v	查找垂直制表符。
\xxx	查找以八进制数 xxx 规定的字符。
\xdd	查找以十六进制数 dd 规定的字符。
\uxxxx	查找以十六进制数 xxxx 规定的 Unicode 字符。

量词

n+	匹配任何包含至少一个 n 的字符串。
n*	匹配任何包含零个或多个 n 的字符串。
n?	匹配任何包含零个或一个 n 的字符串。
n{X}	匹配包含 X 个 n 的序列的字符串。
n{X,Y}	匹配包含 X 至 Y 个 n 的序列的字符串。
n{X,}	匹配包含至少 X 个 n 的序列的字符串。
n$	匹配任何结尾为 n 的字符串。
^n	匹配任何开头为 n 的字符串。
?=n	匹配任何其后紧接指定字符串 n 的字符串。
?!n	匹配任何其后没有紧接指定字符串 n 的字符串。

支持正则表达式的 String 对象的方法

search	检索与正则表达式相匹配的值。	
match	找到一个或多个正则表达式的匹配。	
replace	替换与正则表达式匹配的子串。	
split	把字符串分割为字符串数组。

RegExp 对象方法

compile	编译正则表达式。	
exec	检索字符串中指定的值。返回找到的值,并确定其位置。
test	检索字符串中指定的值。返回 true 或 false。

python 正则表达式

re 模块使 Python 语言拥有全部的正则表达式功能。

match方法

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

re.match(pattern, string, flags=0) 我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

group(num=0) 匹配的整个表达式的字符串

group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。

groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

search方法

re.search 扫描整个字符串并返回第一个成功的匹配。 函数语法:

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

我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

检索和替换

Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。 语法:

re.sub(pattern, repl, string, count=0, flags=0) 参数:

pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
import re
 
# 将匹配的数字乘以 2
def double(matched):
    value = int(matched.group('value'))
    return str(value * 2)
 
s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))

flags

flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:

re.I 忽略大小写
re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
re.M 多行模式
re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
re.X 为了增加可读性,忽略空格和 # 后面的注释

re.compile 函数

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。 语法格式为:

re.compile(pattern[, flags])

findall

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

注意: match 和 search 是匹配一次, findall 匹配所有。

语法格式为:

findall(string[, pos[, endpos]])

re.finditer

和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

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

re.split

split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:

re.split(pattern, string[, maxsplit=0, flags=0])

正则表达式模式

模式	描述
^	匹配字符串的开头
$	匹配字符串的末尾。
.	匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...]	用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
[^...]	不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re*	匹配0个或多个的表达式。
re+	匹配1个或多个的表达式。
re?	匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n}	精确匹配 n 个前面表达式。例如, o{2} 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的两个 o。
re{ n,}	匹配 n 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。"o{1,}" 等价于 "o+"。"o{0,}" 则等价于 "o*"。
re{ n, m}	匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b	匹配a或b
(re)	匹配括号内的表达式,也表示一个组
(?imx)	正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx)	正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re)	类似 (...), 但是不表示一个组
(?imx: re)	在括号中使用i, m, 或 x 可选标志
(?-imx: re)	在括号中不使用i, m, 或 x 可选标志
(?#...)	注释.
(?= re)	前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re)	前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
(?> re)	匹配的独立模式,省去回溯。
\w	匹配字母数字及下划线
\W	匹配非字母数字及下划线
\s	匹配任意空白字符,等价于 [\t\n\r\f].
\S	匹配任意非空字符
\d	匹配任意数字,等价于 [0-9].
\D	匹配任意非数字
\A	匹配字符串开始
\Z	匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z	匹配字符串结束
\G	匹配最后匹配完成的位置。
\b	匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B	匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等.	匹配一个换行符。匹配一个制表符。等
\1...\9	匹配第n个分组的内容。
\10	匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。

正则表达式:

r'(.*) are (.*?) .*'

解析: 前面的一个 r 表示字符串为非转义的原始字符串

 (.*) 第一个匹配分组,.* 代表匹配除换行符之外的所有字符。
 (.*?) 第二个匹配分组,.*? 后面多个问号,代表非贪婪模式,也就是说只匹配符合条件的最少字符
 后面的一个 .* 没有括号包围,所以不是分组,匹配效果和第一个一样,但是不计入匹配结果中。

逻辑分组

分组就是用一对圆括号“()”括起来的正则表达式,匹配出的内容就表示一个分组。从正则表达式的左边开始看,看到的第一个左括号“(”表示第一个分组,第二个表示第二个分组,依次类推,需要注意的是,有一个隐含的全局分组(就是0),就是整个正则表达式。

分完组以后,要想获得某个分组的内容,直接使用group(num)和groups()函数去直接提取就行。

提取代码中的超链接中的文本

s='<div><a href="https://support.google.com/chrome/">更多</a><p>dfsl</p></div>'

print re.search(r'<a.*>(.*)</a>',s).group(1)
print re.match(r'.*<a.*>(.*)</a>',s).group(1)

命名分组 就是给具有默认分组编号的组另外再给一个别名。命名分组的语法格式如下:

(?P<name>正则表达式)#name是一个合法的标识符

如:提取字符串中的ip地址

s = "ip='230.192.168.78',version='1.0.0'"
re.search(r"ip='(?P<ip>\d+\.\d+\.\d+\.\d+).*", s)
res.group('ip')#通过命名分组引用分组
'230.192.168.78'

当用”()”定义了一个正则表达式组后,正则引擎则会把被匹配的组按照顺序编号,存入缓存。这样我们想在后面对已经匹配过的内容进行引用时,就可以用”\数字”的方式或者是通过命名分组进行”(?P=name)“进行引用。\1表示引用第一个分组,\2引用第二个分组,以此类推,\n引用第n个组。而\0则引用整个被匹配的正则表达式本身。这些引用都必须是在正则表达式中才有效,用于匹配一些重复的字符串。

#通过命名分组进行后向引用
re.search(r'(?P<name>go)\s+(?P=name)\s+(?P=name)', 'go go go').group('name')
'go'
#通过默认分组编号进行后向引用
re.search(r'(go)\s+\1\s+\1', 'go go go').group()
'go go go' 

#交换位置
s = 'abc.xyz'
re.sub(r'(.*)\.(.*)', r'\2.\1', s)
'xyz.abc'

前向肯定断言的语法:(?=pattern) 后向肯定断言的语法:(?<=pattern)

前向否定断言语法:(?!pattern) 后向否定断言语法:(?<!pattern)

获取c语言代码中的注释内容
s1='''char *a="hello world"; char b='c'; /* this is comment */ int c=1; /* t
his is multiline comment */'''
re.findall( r'(?<=/\*).+?(?=\*/)' , s1 ,re.M|re.S)
[' this is comment ', ' this is multiline comment ']


#提取不是.txt结尾的文件
>>> f1 = 'aaa.txt'
>>> re.findall(r'.*\..*$(?<!txt$)',f1)
[]
#提取不以数字开头的文件
>>> re.findall(r'^(?!\d+).*','1txt.txt')
[]
#提取不以数字开头不以py结尾的文件
>>> re.findall(r'^(?!\d+).+?\..*$(?<!py$)','test.py')
[]
>>> re.findall(r'^(?!\d+).+?\..*$(?<!py$)','test.txt')
['test.txt']

|	匹配|表达式左右的任意一个	abc|def		abc	def
(?P<name>...) 分组除原有编号外,再加一个别名	(?P<id>abc){2}	abcabc

(?P=name)	应用别名为name的分组匹配到的字符串	(?P<id>abc)ee(?P=name)	abceeabc

特殊构造(不分组)
(?:...)	(...)的不分组版本,用于|或后接数量词	(?:abc){2}	abcabc
(?iLmsux)	iLmsux中的每个字符代表正则表达式的一种匹配模式,只能用在正则表达式开头,可选多个	(?i)abc	AbC
(?#...)	将#后面的字符当做注释忽略	abc(?#comment)def	abcdef

参考:

  1. JavaScript 简介
  2. python 正则表达式
  3. python 正则 分组