正则表达式
介绍
什么是正则表达式?
正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
简而言之,正则表达式是用来匹配字符串的一种字符串模式(pattern)。
语法
1. 普通字符
普通字符可以是任何可见字符,如字母(a-z, A-Z)、数字(0-9)、符号(~!@#$%^&*()-=)等。
例如:
正则表达式python
可以匹配到python is a language for data analyze.
中的python
,但匹配不到别的字符,这与普通的文本搜索无异。
正则表达式12306
可以匹配到The phone number for booking a train tickets is 12306.
中的12306
。
2. 不可见字符
不可见字符,又叫非打印字符,简单来说就是肉眼不可见的字符,如空格符、制表符、换行符、回车符等,详见下表:
字符 | 描述 |
---|---|
cx | 匹配由x指明的控制字符。例如, cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。 |
f | 匹配一个换页符。等价于 x0c 和 cL。 |
匹配一个换行符。等价于 x0a 和 cJ。 | |
匹配一个回车符。等价于 x0d 和 cM。 | |
s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ f v]。注意 Unicode 正则表达式会匹配全角空格符。 |
S | 匹配任何非空白字符。等价于 [^ f v]。 |
匹配一个制表符。等价于 x09 和 cI。 | |
v | 匹配一个垂直制表符。等价于 x0b 和 cK。 |
回车符与换行符的区别:在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。
例如:
正则表达式pythSn
可以匹配python
。
正则表达式Tosbe
可以匹配To be no.1
中的To be
。
3. 特殊字符
特殊字符,类似于编程语言里面的关键字和保留字,是正则表达式内置语法中的字符,具有特殊意义,如果需要匹配这些特殊字符,需要对其进行转义,如.
。
特别字符 | 描述 |
---|---|
$ | 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ' ' 或 ' '。要匹配 $ 字符本身,请使用 $。 |
( ) | 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。 |
* | 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。 |
+ | 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。 |
. | 匹配除换行符 之外的任何单字符。要匹配 . ,请使用 . 。 |
[ | 标记一个中括号表达式的开始。要匹配 [,请使用 [。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。 |
将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。' ' 匹配换行符。序列 '\' 匹配 "",而 '(' 则匹配 "("。 | |
^ | 匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 ^。 |
{ | 标记限定符表达式的开始。要匹配 {,请使用 {。 |
例如:
4. 限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。
字符 | 描述 |
---|---|
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "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?'。请注意在逗号和两个数之间不能有空格。 |
例如:
5. 定位符
定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。
字符 | 描述 |
---|---|
^ | 匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 或 之后的位置匹配。 |
$ | 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 或 之前的位置匹配。 |
匹配一个单词边界,即字与空格间的位置。 | |
B | 非单词边界匹配。 |
6. 选择
用圆括号 () 将所有选择项括起来,相邻的选择项之间用 | 分隔。
() 表示捕获分组,() 会把每个分组里的匹配的值保存起来, 多个匹配值可以通过数字 n 来查看(n 是一个数字,表示第 n 个捕获组的内容)。
例如:
7. 反向引用
可以在同一个正则表达式中引用前面匹配到的内容,使用数字
来获得引用,数字范围是1-99,如1
。
例如:
示例
网易新闻新闻标题提取
<td class=".+?"><span>d+</span><a href=".+?">(.+?)</a></td>
Linux终端中的正则表达式
grep
命令
grep
命令用于从文件中检索文本。
egrep
:即grep -E
grep -E -o "a target="_blank" title=".*?" href" testfile.txt
// example.json
// 假设需要提取所有title,此时可以使用grep命令
{
"status": 0,
"data": {
"news": [
{
"id": "xxxxxxxxxxxx",
"title": "1.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "2.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "3.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "4.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "5.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "6.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "7.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "8.测试新闻标题"
},
]
}
}
grep -E ""title": ".*?"" example.json
或egrep ""title": ".*?"" example.json
sed
命令
sed
命令用于处理文本。
egrep -o "a target="_blank" title=".*?" href" testfile.txt | sed -E "s/(a |target="_blank"|title="|" href)//g"
// example.json
// 假设需要去掉title中的序号,手工操作需要一个一个删除,此时可以使用sed命令
{
"status": 0,
"data": {
"news": [
{
"id": "xxxxxxxxxxxx",
"title": "1.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "2.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "3.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "4.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "5.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "6.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "7.测试新闻标题"
},
{
"id": "xxxxxxxxxxxx",
"title": "8.测试新闻标题"
},
]
}
}
sed -E "s/"title": "[0-9]+./"title": "/g" example.json
总结
编写正则表达式的几个步骤:
- 确定要提取的内容。
- 确定目标内容具有可提取的特征。
- 确定会变化的部分和不会变化的部分。
- 确定好哪些字符需要转义。
- 编写正则表达式。