正则表达式

参考 正则表达式30分钟入门教程

元字符——元字符(Metacharacter)是拥有特殊含义的字符
序号 元字符 描述
. 查找单个字符,除了换行和行结束符。
\w 查找单词字符。等价于[a-zA-Z0-9_]。
\W 查找非单词字符。等价于[^a-zA-Z0-9_]。
\d 查找数字,等价于[0-9]。
\D 查找非数字字符,等价于[^0-9]。
\s 查找空白字符,包括空格、换行、回车、制表符等等,[ \n\r\t\v\f]。
\S 查找非空白字符。
\b 匹配单词边界,例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
\B 匹配非单词边界。
\0 查找 NUL 字符。
\n 查找换行符。
\f 查找换页符。
\r 查找回车符。
\t 查找制表符。
\v 查找垂直制表符。
^ 匹配字符串开始的位置,如果设置了多行,匹配\r或\n 之后的位置。
$ 匹配字符串结束的位置,如果设置了多行,匹配\r或\n 之前的位置。
量词
序号 量词 描述
* 匹配0次、1次或者多次,等价于{0,}。
+ 匹配1次或者多次,等价于{1,}。
? 匹配0次、1次,等价于{0,1}。
{n} 匹配 n 次。
{n,} 匹配至少 n 次。
{n,m} 匹配 n 到 m 次。
方括号
序号 表达式 描述
[abc] 字符集,匹配当中的任何一个字符。
[^abc] 匹配不包含的任何字符。
[0-9] 匹配数字字符,等价于\d 或者 [0123456789]。
[a-z] 匹配26个小写英文字符。
捕获与非捕获
序号 表达式 说明
(pattern) 匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。
(?:pattern) 匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
(?=pattern) 正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
(?<=pattern) 反向肯定预查,与正向肯定预查类拟,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
(?<!pattern) 反向否定预查,与正向否定预查类拟,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。

贪婪匹配与非贪婪匹配:当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。

C/C++ 正则表达式

在头文件 regex 中有关于正则表达式的实现和接口。

cmatch、smatch 类保存匹配结果。

参考C++标准库中正则表达式的使用

JavaScript 的正则表达式

字面量语法:
var p = /pattern/attribute ;
RegExp对象语法:
var p = new RegExp(pattern, attribute) ;
参数:
pattern 是字符串,指定了正则表达式的模式。
attribute 是一个可选的字符串,包括"g"(全局),"i"(忽略大小写),"m"(多行,此模式下,字符串中有回车或换行,^和$ 匹配行首和行尾)。
返回值:
一个新的 RegExp 对象,具有指定的模式和标志。如果参数 pattern 是正则表达式而不是字符串,那么 RegExp() 构造函数将用与指定的 RegExp 相同的模式和标志创建一个新的 RegExp 对象。
如果不用 new 运算符,而将 RegExp() 作为函数调用,那么它的行为与用 new 运算符调用时一样,只是当 pattern 是正则表达式时,它只返回 pattern,而不再创建一个新的 RegExp 对象。

查找本网页上的超链接地址。

var html = document.querySelector("body").innerHTML;
var p = /(?<=href\s*?=\s*?").*?(?=" *)/g;
var r = html.match(p);
console.log(r); 

PowerShell 的正则表达式

PowerShell 使用Regex 类来实现正则表达式,命名空间是 System.Text.RegularExpressions。在PowerShell 中可直接使用regex。

Regex 类的常用方法。

IsMatch
通过调用 IsMatch 方法确定输入文本中是否具有正则表达式模式匹配项。
Regex.IsMatch(string, pattern)
Match、Matches
通过调用 Match 或 Matches 方法检索匹配正则表达式模式的一个或所有文本匹配项。
第一个方法返回提供有关匹配文本的信息的 Match 对象。 第二个方法返回 MatchCollection 对象,该对象对于在分析的文本中找到的每个匹配项包含一个 Match 对象。
Replace
通过调用 Replace 方法替换匹配正则表达式模式的文本。
$p = New-Object System.Text.RegularExpressions.Regex('(?<=href\s*?=\s*?").*?(?=" *)') 
$p = [regex]('(?<=href\s*?=\s*?").*?(?=" *)')
$html = @"
        <nav class="navbar navbar-default">
            ......    
        </div>
"@
$r =[System.Text.RegularExpressions.Regex]::Matches($html, $p)
$r = [regex]::Matches($html, $p)
$r|ForEach-Object{$_.value}

Python 正则表达式

Python 中的正则表达式由 re 模块提供。由于\ 在字符串中有转意的作用,与正则表达式冲突,通常需要双斜杠(\\),可以使用r'string' 语法,r表示字符字面量,不转意。

re.compile(pattern, flags=0)
将正则表达式模式编译成一个正则表达式对象,它可以用于匹配使用它的match ()和search ()方法。
re.I、re.IGNORECASE
执行不区分大小写的匹配 ;如[A-Z]表达式将太匹配小写字母。这不被受当前的区域设置。
re.M、re.MULTILINE
当指定时,模式字符' ^'匹配字符串的开头以及每个行的开头(紧接每个换行符); 模式字符'$'匹配字符串的末尾以及每一行的结尾(紧靠每个换行符之前)。默认情况下, '^'只匹配字符串的开始,'$'只匹配字符串的末尾和字符串末尾换行符(如果有的话)之前的位置。
re.S、re.DOTALL
使'.'特殊字符匹配任何字符,包括换行 ;如果没有此标志, '.'将匹配任何内容除换行符。
re.search(pattern, string, flags=0)
扫描字符串,寻找的第一个由该正则表达式模式产生匹配的位置,并返回相应的MatchObject实例。返回None如果没有字符串中的位置匹配模式 ;请注意这不同于在字符串的某个位置中找到一个长度为零的匹配。
re.findall(pattern, string, flags=0)
返回一个迭代器符合MatchObject情况 在 RE模式字符串中的所有非重叠的匹配。该字符串是扫描的左到右,和按发现的顺序返回匹配。空匹配包含在结果中,除非他们接触的另一个匹配的开头。

获取网页中的URL。

import requests
import re

url = 'https://jackleegithub.github.io/regExp.html';
r = requests.get(url);
html = r.text

p = re.compile(r'(?<=href=").*?(?=")');
urls = re.findall(p, html)

for url in urls:
    print(url)

总结

正则表达式都是第三方类(库,模块)提供支持,模式字符串的字面量书写会有细微差别,JS和Python 感觉最好;类库都提供了模式匹配、查找、替换的方法,JS主要是字符串提供方法。