正则表达式,可谓是相当常用的东西了,看起来就是一堆奇怪的符号。正则表达式的强大之处就是在构建一个文本的规则
这次就对正则表达式做一个简单的学习记录吧。
简介
正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。
正则表达式的功能
- 测试字符串内的模式。
例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。 - 替换文本。
可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。 - 基于模式匹配从字符串中提取子字符串。
可以查找文档内或输入域内特定的文本。
语法
如果我们把一个正则表达式看作一个字符串,在这个字符串里面有这样的 几类字符:
- 普通字符 / 非打印字符
- 特殊字符
- 限定字符
普通字符 包括没有被指定为元字符的 所有可打印与不可打印字符。有 大小写字母,数字,标点符号,一起其他符号
Tips
\n = 0x0a
\r = 0x0d
CRLF = \r\n
LF = \n
符号 | 描述 |
---|---|
* | 匹配前子表达式的零次或多次匹配 |
+ | 匹配前面表达式一次以上不允许0 |
. | 匹配换行(\n)以外的的单字符 |
^ | 匹配开始 转义使用 \^ |
$ | 匹配结束 转义使用 \$ |
( ) | 子表达式的开始结束 |
[] | 中括号表达式 |
? | 匹配0次或者一次 |
\ | 用于转义 如 \n 即匹配换行 |
{} | 标记限定符 |
| | 两项间选择 |
题外话:这里的
|
符号在表格里面,由于是用来制表的,所以这里使用特殊方法|
来输出
限定符
限定符用于指定一个匹配部分需要被匹配的限定(匹配次数)。
*, +, ?, {n},{n,},{n,m}
符号 | 描述 | 示例 |
---|---|---|
* | 匹配前面子表达式0或多次 | ‘ab*‘ re abbb or a |
+ | 匹配一次或多次 | 同上无 a |
? | 零次或一次 | ab or a |
{n} | 匹配指定次 | ab(n个) |
{n,} | 匹配指定次以上 | ab(n个以上b) |
{n,m} | 区间,最少n次最多m次 | 同理 |
之前一直以为 * 是任意通配符,导致了好多的问题
在这里是网页的例子
/<.*>/ # 这个正则乍一看还是不懂,慢慢看
/<.*?>/
慢慢看,发现其实可以理解,首先,<> 通过转义就是领个符号,那么就是匹配中间的部分。
. 代表着除了换行以为的单字符。后面的 * 说明0次或多次匹配前面的子表达式,那么连起来这里的意思就是,匹配一个任意的字符串。比如 <1231231212>.
*,+ 匹配时贪婪的 这里说的时这个匹配的贪婪性。 如果有这样的一个字符串 :<123>123<123> 那么使用上面的第一个正则表达式 ,得到的匹配结果,就是 最开始的 < 到最后的 > 之间的所有内容。
所以,实现非贪婪的匹配,这里使用了第二个表达式, 理解起来,就是在前面的匹配任意字符串的子表达式 上添加了只匹配一次的条件,这样的匹配时非贪婪的。如果同样的是 <123>123<123> 这里得到的结果就是 <123> 而已。
定位符
符号 | 描述 |
---|---|
^ | 匹配字符串开始的位置 |
$ | 匹配字符串的结束位置 |
\b | 匹配一个单词边界 如空格 |
限定符和定位符,不允许同时出现。
如果是从头开始匹配一个文本的话,就使用 ^ ,如果是匹配结束处的内容就是使用 $ 在末尾。如果是单行匹配,这里使用 ^…$
基本模式匹配
abc
^abc
abc$
^abc$
第一项匹配所有包含该串的内容
第二项只匹配 以该串开头的内容
第三项匹配 以该串结尾的内容
第四项只匹配该串
其他符合
符合 | 描述 | 示例 |
---|---|---|
\ | 表达式或操作 | |
[] | 字符集合 | [abc] or [a-b] |
[^] | 负字符集合 | [^asd] 不匹配其中的字符 |
[a-z] | ||
[^a-z] |
应用
这里收集正则在几个语言下的应用:
python
在 pyhton 下的正则模块是 re
字符串的正则检测
re.match(pattern, string, flags=0)
>>> import re
>>> print( re.match('[ca]+', 'acacac'))
<re.Match object; span=(0, 6), match='acacac'>
对于字符串的正则提取
>>> import re
>>> matched_list = re.compile(r'a+').find('aaa')
>>> re.compile(r'a+b*').findall('aaabasd')
['aaab', 'a']
>>> print( re.search('[ca]+', 'acacac').group())
acacac
>>> print( re.search('[0-9]+\.php$', '123.php').group())
123.php
>>> print( re.search('[0-9]+\.php$', '12asd3.php').group())
3.php
JavaScrip
对于字符串的提取
a='assid123'
> (a).match("[0-9]*$")[0]
"123"
> (a).match("^[0-9]*")[0] // 这里没有以数字开头
""
Nginx Conf
对于正则表达式在 Nginx 的配置文件里面的应用也是相当的广泛 了
location ~ \.php$ {
proxy_pass http://127.0.0.1;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}
上面的是 Nginx.conf 里面的实例配置,从功能上讲,前者是使用 Nginx 作为转发,如注释说明,最后是apache 对php 进行解析执行。后者是使用 fastcgi ,使用 php-fpm 进行脚本执行。
不过重点的正则表达式可以看见
~ \.php$
这里值得注意的是 ~
并不是标准的正则表达式里的东西。而是Nginx 里特有的,表示该匹配时大小写敏感的。
记得之前有句话,web 安全里的,怎么判断主机是linux 还是 windows 答曰改变 URL 的大小写。这里看来也是不一定正确的。
后面的部分,可以看出 \.
是对dot 的转义,说明其是字符点,不是匹配任意单字符的意思。总体可见该正则的意思是,对.php 进行匹配。如果如果匹配到 .php 的url 之后,就把请求传递给 CGI 处理任务了。
参考链接:
Nginx 在URL 匹配上还有自己的限定符号
后
再也不会看到正则就发晕了,至少简单的可以看懂一些,这个 post 也算是纠正了自己的一些误区吧。加油~
有一盒月饼也不会开心,中秋快乐~