暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

正则表达式知识分享

IT那活儿 2021-05-15
428

一.正则的简介
正则表达式主要是按照指定规则来匹配相应的字符串信息。正则表达式这个概念最初是由Unix中的工具软件(grep等)普及开的,现在许多编程语言也都支持使用正则进行匹配。
如上图所示,正则表达式中的. [] ^ $符号在Linux的不同系统工具或者不同开发语言中均适用;(),{},?,+,|等在不同的工具或语言中适用性有差别,主要是因为不同工具或语言遵循的正则表达式规范不同引起的。例如:在使用grep系统工具时发现,对于{}()等特殊符号有的需要转义,有的不要转义。

二.正则表达式规范
Unix/Linux下的工具大多采用POSIX规范,该规范包含基本语法(BRE)和扩展语法两种(ERE)两种,其中扩展语法不能理解为对基本语法的扩充,其本身也是一套完整规范。
另外一种从Perl衍生出来,叫做PCRE规范,当然还有其他的规范,这里就不多做介绍。
以grep为例,来演示如何在Linux系统中去切换到各种规范下使用正则表达式。
基本语法:  grep “^#\{1,\}”/etc/fstab
基本语法中,{}()等特殊符号需要转译的,如果使用扩展语法或PCRE规范不需要。
扩展语法:grep -E “^#{1,}”/etc/fstab   或者  egrep “^#{1,}” etc/fstab
通过添加-E参数或者使用egrep命令来切换到扩展语法规范。
PCRE规范:grep -P “^#{1,}”/etc/fstab
注意Linux系统需要加载PCRE依赖包,通过添加-P参数切换到PCRE规范。

三.正则的特殊字符

1.  常用的元字符

.  匹配除换行符以外的任意一个字符 ^  匹配字符串的开始位置$  匹配字符串的结束位置\w  匹配字母和数字以及下划线其中的一个字符,相当于[_a-zA-Z0-9]\W  匹配不是字母、数字、下划线的字符,即\w的补集\d  匹配任意一个数字,相当于[0-9]\D  匹配任意非数字的字符,\d的补集\b  匹配单词的开头或结尾位置,用于精确匹配 \bevening\b  Good evening leveningll 仅匹配是evening的完整单词\B  匹配不是单词开头或结束的位置\Bveni\B    Good evening veni 仅匹配单词内部含veni的字符串\s  匹配空格符号 \S  匹配非空格符号

2.  常用量词

常用量词主要是对前面的字符的匹配次数

*   代表连续匹配前边的内容任意次(换行符除外) +   和*类似,不同的是*可以匹配0次,而+则是匹配至少1次?   匹配0次或1次{n}  匹配前面的字符n次 {n,}  匹配前面的字符至少n次{n,m}  匹配前面的字符n次到m次

3. 字符集合

[xyz]       匹配x或y或z[a-zA-Z0-9] 匹配a-z或A-Z或0-9中任意一个字符[^a-z]      匹配非a-z的任意字符,达到了取反的效果

4.  其他的特殊字符

()  以组的形式将多个字符作为一个整体。

如(abc){2,} 表示至少是abcabc。在一个表达式中使用多个()定义组,则使用\1,\2的形式来调用的定义的组。

|   或条件 把不同的规则分开,按照顺序进行匹配,其中一个匹配成功,即匹配结束

5.  贪婪匹配和惰性匹配

.*  表示贪婪匹配   a.*b    最先出现a到最后出现的b   cca000bccccaccbcab
.*? 表示惰性匹配   a.*?b   最先出现a到最先出现的b   cca000bccccaccbcab

6.  断言匹配

(?=exp)  匹配exp前面位置的字符
(?<=exp) 匹配exp后面的位置的字符
此处仅列举了较简单的两个示例,还有一些其他的复杂,有兴趣的可以网上查看下。

7. PCRE规范与Linux中工具使用规范的不同

  • vi/vim,grep,sed等工具遵循的是POSIX的基本语法规范,awk和egrep遵循的是POSIX扩展语法规范。因此,这是有的对{}进行转义,有的不需要转义的原因。

  • PCRE中常用\b来表示“单词的起始或结束位置”,但Linux/Unix的工具中,通常用\<来匹配“单词的起始位置”,用\>来匹配“单词的结束位置”,sed中的\y可以同时匹配这两个位置。

  • 不同规范中分枝匹配也有一定差别,有的用...|...,而有的用(...|...)。

  • 使用()可以定义作用范围,当在一个规则中使用多个括号时,可以使用\1 \2来调用前面括号的内容。

8.  POSIX字符组

我们在使用正则表达式时,也会遇到像[:digit:]表示数字字符、[:lower:]表示小写字母字符的形式,这种形式就是POSIX字符组。POSIX字符在不同的字符集中对应的格式也不一样,在ASCII中,对应关系如下:

9.  正则表达式举例

1)扩展正则表达式表示IP的方式
拆分255的过程如下:
数值范围:            对应的表达式
0-9                              [0-9]
10-99                         [1-9][0-9]
100-199                     1[0-9]{2}
200-249                     2[0-4][0-9]
250-255                     25[0-5]
0-255的表达式为:  ( [1-9]?[0-9] | 1[0-9]{2} | 2[0-4][0-9] | 25[0-5] )
IP格式的整体表达式:
(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])
2)扩展正则匹配网址URL:
^(((ht|f)tps?)://|(www\.)?)\w.*(\.(com|cn|io|html))$
拆分如下:
((ht|f)tps?)   匹配http,https,ftp三种格式(www\.)?        ?代表可以匹配0次或者1次www.\w.*           表示可以输入任意内容(换行符除外)(\.(com|cn|io|html|htm|))$  可以匹配comcn、io、html等结尾的网址

因此以下形式的网址均可以被匹配:

http://aa.123.com
ftp://aa.sss.sss.com
http://bb.com
www.aa.cn
aa.com
四.正则表达式在nginx中的应用案例

在编译安装nginx前,需要安装PCRE依赖包,nginx中的正则是遵循PCRE规范。

1. 正则匹配在location模块中的使用

location模块中主要有以下几种匹配的形式
=      #进行普通字符精确匹配
^~    #不使用正则匹配,对uri路径进行前缀匹
         配,并且在正则之前。
~      #表示执行一个正则匹配,区分大小写
~*    #表示执行一个正则匹配,不区分大小写
/       # 对前缀进行匹配。
这些匹配方式的优先级顺序:
(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (location )
借助location的匹配规则可以对一些特殊请求转发到指定的应用,达到正向或反向分流的作用。
location ~* \.(gif|jpg|jpeg)$ {
# 匹配以 gif, jpg, or jpeg结尾的请求

2. 正则匹配在中if模块中的应用

if模块借助nignx的内部变量来进行“~”(大小写敏感)和“~*”(大小写不敏感)正则匹配
举例:nginx做反爬虫的策略

if ($http_user_agent ~* (mobile|nokia|iphone|ipad|android|samsung|htc|blackberry)) {    return 403;   }----------------------------------------------、

3. 正则匹配基于域名的应用


server{    listen 80;    server_name ~ ^(www\.)?(.+)$;    index index.php index.html;    root data/wwwsite/$2;   }

#此处需要说明的一点是在nginx中$2是对前面括号内容的的引用,引用的是(.+),使用该正则可以用一个规则表达式区分不同域名对应的家目录。

访问 www.yewu.com的域名,其的站点家目录结构为/data/wwwsite/yewu.com
访问 www.xuqiu.com的域名,其的站点家目录结构为/data/wwwsite/xuqiu.com

END


更多精彩干货分享

点击下方名片关注

IT那活儿

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论