正则简明

正则简明

正则表达式,可谓是相当常用的东西了,看起来就是一堆奇怪的符号。正则表达式的强大之处就是在构建一个文本的规则

这次就对正则表达式做一个简单的学习记录吧。

简介

正则表达式(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次 同理

之前一直以为 * 是任意通配符,导致了好多的问题

在这里是网页的例子

1
2
/<.*>/		# 这个正则乍一看还是不懂,慢慢看
/<.*?>/

慢慢看,发现其实可以理解,首先,<> 通过转义就是领个符号,那么就是匹配中间的部分。

. 代表着除了换行以为的单字符。后面的 * 说明0次或多次匹配前面的子表达式,那么连起来这里的意思就是,匹配一个任意的字符串。比如 <1231231212>.

*,+ 匹配时贪婪的 这里说的时这个匹配的贪婪性。 如果有这样的一个字符串 :<123>123<123> 那么使用上面的第一个正则表达式 ,得到的匹配结果,就是 最开始的 < 到最后的 > 之间的所有内容。

所以,实现非贪婪的匹配,这里使用了第二个表达式, 理解起来,就是在前面的匹配任意字符串的子表达式 上添加了只匹配一次的条件,这样的匹配时非贪婪的。如果同样的是 <123>123<123> 这里得到的结果就是 <123> 而已。

定位符

符号 描述
^ 匹配字符串开始的位置
$ 匹配字符串的结束位置
\b 匹配一个单词边界 如空格

限定符和定位符,不允许同时出现。

如果是从头开始匹配一个文本的话,就使用 ^ ,如果是匹配结束处的内容就是使用 $ 在末尾。如果是单行匹配,这里使用 ^…$

基本模式匹配

1
2
3
4
abc 
^abc
abc$
^abc$

第一项匹配所有包含该串的内容

第二项只匹配 以该串开头的内容

第三项匹配 以该串结尾的内容

第四项只匹配该串

其他符合

符合 描述 示例
\ 表达式或操作 a \ zxc 匹配a或者zxc
[] 字符集合 [abc] or [a-b]
[^] 负字符集合 [^asd] 不匹配其中的字符
[a-z]
[^a-z]

应用

这里收集正则在几个语言下的应用:

python

在 pyhton 下的正则模块是 re

字符串的正则检测

1
2
3
4
re.match(pattern, string, flags=0)
>>> import re
>>> print( re.match('[ca]+', 'acacac'))
<re.Match object; span=(0, 6), match='acacac'>

对于字符串的正则提取

1
2
3
4
5
6
>>> 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
1
2
3
4
>>> print( re.search('[0-9]+\.php$', '123.php').group())
123.php
>>> print( re.search('[0-9]+\.php$', '12asd3.php').group())
3.php

JavaScrip

对于字符串的提取

1
2
3
4
5
a='assid123'
> (a).match("[0-9]*$")[0]
"123"
> (a).match("^[0-9]*")[0] // 这里没有以数字开头
""

Nginx Conf

对于正则表达式在 Nginx 的配置文件里面的应用也是相当的广泛 了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# proxy the PHP scripts to Apache listening on 127.0.0.1:80

location ~ \.php$ {
proxy_pass http://127.0.0.1;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000

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 进行脚本执行。

不过重点的正则表达式可以看见

1
~ \.php$

这里值得注意的是 ~ 并不是标准的正则表达式里的东西。而是Nginx 里特有的,表示该匹配时大小写敏感的。

记得之前有句话,web 安全里的,怎么判断主机是linux 还是 windows 答曰改变 URL 的大小写。这里看来也是不一定正确的。

后面的部分,可以看出 \. 是对dot 的转义,说明其是字符点,不是匹配任意单字符的意思。总体可见该正则的意思是,对.php 进行匹配。如果如果匹配到 .php 的url 之后,就把请求传递给 CGI 处理任务了。

参考链接:

Nginx 在URL 匹配上还有自己的限定符号

再也不会看到正则就发晕了,至少简单的可以看懂一些,这个 post 也算是纠正了自己的一些误区吧。加油~

有一盒月饼也不会开心,中秋快乐~

-------------本文结束感谢您的阅读-------------
Thanks anyway!