前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >正则表达式教程

正则表达式教程

作者头像
老高的技术博客
发布2022-12-24 12:30:57
1.9K0
发布2022-12-24 12:30:57
举报
文章被收录于专栏:老高的技术博客

正则表达式入门

概念

字符是计算机软件处理文字时最基本的单位,可能是字母,数字,标点符号,空格,换行符,汉字等等。字符串是0个或更多个字符的序列。文本也就是文字,字符串。 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。


支持

在最近的六十年中,正则表达式逐渐从模糊而深奥的数学概念,发展成为在计算机各类工具和软件包应用中的主要功能。不仅仅众多UNIX工具支持正则表达式,近二十年来,在WINDOWS的阵营下,正则表达式的思想和应用在大部分 Windows 开发者工具包中得到支持和嵌入应用!从正则式在Microsoft Visual Basic 6 或 Microsoft VBScript到.NET Framework中的探索和发展,WINDOWS系列产品对正则表达式的支持发展到无与伦比的高度,几乎所有 Microsoft 开发者和所有.NET语言都可以使用正则表达式。如果你是一位接触计算机语言的工作者,那么你会在主流操作系统(*nix[Linux, Unix等]、Windows、HP、BeOS等)、主流的开发语言(PHP、C#、Java、C++、VB、Javascript、Ruby以及python等)、数以亿万计的各种应用软件中,都可以看到正则表达式优美的舞姿。

以上内容引自百度百科


[TOC]

测试工具

在线版

http://regex.larsolavtorvik.com/ http://tool.oschina.net/regex http://www.rubular.com/ http://zhengze.51240.com/ http://www.kingshang.com/ http://zhengze.51240.com/

离线版

正则表达式测试器c#绿色版 正则表达式测试英文版 更多下载


规则

通配符

还记得*通配符吗?

如果要找到所有pdf文件,就在文件管理器中输入*.pdf即可。一般的搜索通配符已经可以很好的对付了,但是如果需要搜索的条件突然变得很复杂:我需要在号码簿里筛选出来北京和陕西省所有的手机号座机号,通配符就表示压力山大了!而这项任务对于正则表达式而言,简直是轻而一举。我相信你看完此文,一定能轻松写出对应的匹配语句!

最基础

9527 10086 regex 这种最平常不过的字符所蕴含的意思就是他们本身

字符组

字符组就是在[](方括号)中列举出所有的可能再去匹配

直接匹配

[0-9] 匹配一个数字

[aeiou] 匹配任何一个英文元音字母

[.?!] 匹配标点符号(.或?或!)。

gr[ae]y 匹配grey 或者 gray

方括号内的多个字符实际上只占一个坑,他无法匹配greay或graay,因为gr[ae]y只匹配四个字母,[ae]只占一个

[Hh][123456] 匹配HTML里所有的h标签,这种写法考虑到了H标签的大小写

代码语言:javascript
复制
PS.在w3c的规范里还是推荐所有html标签都必须是小写字母,所有属性都使用双引号包裹
排除型匹配

gr[^ae]y 匹配除了grey和gray以外的所有单词 h[^123] 匹配不是h1,h2,h3的标签

元字符

元字符就是在正则语言中代表特殊意义的字符,如

[0-9]代表的含意与\d一样

[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)。

^代表每一行的开始,$代表每一行的结束

^$ 匹配空行

^foot$ 匹配只有foot一个词的行

元字符的出现可以理解为方便书写

基础元字符表

代码

说明

.

匹配除换行符以外的任意字符

\w

匹配字母或数字或下划线或汉字

\W

匹配任意不是字母或数字或下划线或汉字的字符

\s

匹配任意的空白符

\S

匹配任意非空白符

\d

匹配数字

\D

匹配非数字

\b

匹配单词的开始或结束

^

匹配字符串的开始

$

匹配字符串的结束

转义

如果要匹配 C:\\WINDOWS,我们要如何描述\反斜杠呢? 这个时候就需要用到转义,在这种特殊标点前面加一个\,他的意思就表示后面的标点是普通的标点,比如\\w匹配字符 \w,这个时候\w就不再表示一个字符了

字符组里面的内容不需要转义

重复

{n} n代表重复次数,前面一定是元字符或者分组 \d{11} 匹配一个11位的数字,如果要匹配手机号码,需要一些改造

代码

说明

\*

重复零次或更多次

\+

重复一次或更多次

\?

重复零次或一次

{n}

重复 n 次

{n,}

重复 n 次或更多次

{n,m}

重复 n 到 m 次

小测试:如何模糊匹配IP地址

重复只对紧邻的上一个最小正则单元起作用,如123*不能匹配123123,可以匹配12333

贪婪

贪婪顾名思义就是尽力的匹配,这也是正则表达式中默认的匹配模式,与此对用的就是另一种模式叫最小匹配,即在能匹配更多的情况下选择放弃,总是返回最小的结果集。

例子:我们现在想找到类似通配符下的a*c下字符,即a开头c结尾的字符串。

代码语言:javascript
复制
abccccbcdda

我们这样写a\w*c,和这样写a\w*?c 得到的结果是不一样的

表达式

结果

a\w*c

abccccbc

a\w*?c

abc

*重复的情况下,后面的?告诉重复符*不要匹配太多,所以当找到第一个c的时候就收手了,而默认情况下匹配到了最后一个c。

所以在写*或{n,m}重复的时候一定要注意是否需要贪婪模式,否则匹配后的结果可能会略过很多可能你需要的信息。

选择分支

在此我们引入一个符号|,他表示或,即程序语言里的or

以下引用自正则表达式30分钟入门教程

代码语言:javascript
复制
\d{5}-\d{4}|\d{5}这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:使用分枝条件时,要注意各个条件的顺序。如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。

括号的作用

界定作用范围

还记得gr[ae]y吗? gr(a|e)y 也可以实现这样的匹配,如果没有括号,gra|ey就成了毫无关系的两部分。

分组和反向引用
正则表达式的匹配和捕获

正则表达式的匹配其实就是点到即止,只要符合表达式的规则即可,但是引入了分组以后,正则表达式就有了更大的发挥空间。

分组使用括号标记出本次匹配需要提取的数据,并且将匹配成功的数据返回给程序供其使用。

对于grey这个单词 gr[ae]ygr(e|a)y 都可以将其匹配,但是对于前者,只能匹配grey,而后者将匹配的内容返回,即捕获了字母e。

代码语言:javascript
复制
PS.分组往往伴随着分隔符出现,但是请不要把二者的真正含义搞混了。

分组所提取出来的值可能不止一组,正则会把他们自动编号,从0(0表示所有匹配)开始,group1是第一个分组,以此类推。分组可以被捕获,以BBCODE为例,下面是源代码

代码语言:javascript
复制
正常文字        
正常文字
我是 [b]粗体字[/b]     Ctrl+B    
我是粗体字
我是[i]斜体字[/i]     Ctrl+I    
我是斜体字
我是[u]下划线文字[/u]     Ctrl+U    
我是下划线文字
我是[s]删除线文字[/s]     Ctrl+D    
我是删除线文字
我是[mask]马赛克文字[/mask]     Ctrl+M    
我是马赛克文字
我是
[color=red]彩[/color][color=green]色[/color][color=blue]的[/color][color=orange]哟[/color]。        
我是
彩色的哟。
[size=10]不同[/size][size=14]大小的[/size][size=18]文字[/size]效果也可实现。        
不同大小的文字效果也可实现。
Bangumi 番组计划: [url]http://chii.in/[/url]     Ctrl+L    
Bangumi 番组计划: http://chii.in/
带文字说明的网站链接:
[url=http://chii.in]Bangumi 番组计划[/url]     Ctrl+L    
带文字说明的网站链接:
Bangumi 番组计划
存放于其他网络服务器的图片:
[img]http://chii.in/img/ico/bgm88-31.gif[/img]

首先,我们用\[([a-z]+)\](.*?)\[\/\1]匹配,最后的\1意思是第一个分组,用来闭合标签,但是发现只能得到前面几个简单的标签,因为我们没有考虑到有些标签是有属性的。

我们修改了刚才的表达式,再用\[([a-z]+)=?(\w*)\](.*?)\[\/\1]去匹配这句话,可以得到标签、属性和内容。

下面我们来分析一下:([a-z]+)用于tag,注意等于号的出现次数,等号后面就是属性,(.*)提取到了标签里的内容,最后引用第一分组使标签闭合!

分组别名

分组在创建时默认的命名为1,2,3,但是你可能为了方便想自己命名,这个功能正则早都考虑到了。只要在分组的前面或后面加入?<groupname>,其中groupname就是你的组名,在后面引用的时候用\k<groupname>引用即可。

所以刚才的表达式可以修改为:

代码语言:javascript
复制
\[(?<tag>[a-z]+)=?(\w*)\](.*?)\[\/\k<tag>]

分组别名可以让正则表达式更容易理解,而且在coding的时候别名会成为键名返回给程序员,简化了很多操作!

上面的正则放在PHP里运行,则会返回以下结果,自动保存了默认组名和别名。

代码语言:javascript
复制
//以上省略
[tag] => Array
    (
        [0] => b
        [1] => i
        [2] => u
        [3] => s
        [4] => mask
        [5] => color
        [6] => color
        [7] => color
        [8] => color
        [9] => size
        [10] => size
        [11] => size
        [12] => url
        [13] => img
    )

[1] => Array
    (
        [0] => b
        [1] => i
        [2] => u
        [3] => s
        [4] => mask
        [5] => color
        [6] => color
        [7] => color
        [8] => color
        [9] => size
        [10] => size
        [11] => size
        [12] => url
        [13] => img
    )
//以下省略

替换

正则表达式的匹配或者提取已经基本讲完了,下面

代码语言:javascript
复制
<?php
    $string = 'April 15, 2003';
    $pattern = '/(\w+) (\d+), (\d+)/i';
    $replacement = '$1,16,$3';
    echo preg_replace($pattern, $replacement, $string);
    //April,16,2003
?>

上面的程序先用正则表达式提取出三个分组,分别匹配了月份,日期和年份。再看变量replacement里的1、3,他们就代表了第一分组和第三分组

我们刚刚学习了分组命名,我们试试修改第二组的命名

代码语言:javascript
复制
<?php
    $string = 'April 15, 2003';
    $pattern = '/(\w+) (?<month>\d+), (\d+)/i';
    $replacement = '$1,16,$2,$3,$month';
    echo preg_replace($pattern, $replacement, $string);
    //April,16,15,2003,$month
?>

结果好像不是我们想要的,看来分组命名在PHP的正则替换里没有作用,以后使用的时候一定要注意!

断言

断言的意思就是预先判断匹配字符的位置,以达到更精确的匹配。源文本如下:

代码语言:javascript
复制
tar rat head tail echo var_dump ma1ke

现在需要找出字母a前面是一个字母v或者r的词,我们使用(?<=[vr])a,即可达到效果。即在原本的条件左边附加(?<=expression)。

现在需要找出字母a后面是一个字母d或者是数字的词,我们使用a(?=(\d|d)),即可达到效果。即在原本的条件右边附加(?=expression)。

断言只是条件,帮你找到真正需要的字符串,本身并不会匹配!所以不用担心他会影响分组编号。

总结

正则表达式水很深,但的确很强大!简单一行规则就包含了十分复杂的逻辑和运算,确实快赶上一门程序语言了,如果你能够掌握他,那么他会极高的提高你的工作效率。

但正则表达式不是一朝一夕就能掌握的,更多的在于理解正则表达式里的精神和情怀,去包容他,放纵他,打碎他,然后创造它!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014-07-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正则表达式入门
    • 概念
      • 支持
        • 测试工具
          • 在线版
          • 离线版
        • 规则
          • 通配符
          • 最基础
          • 字符组
          • 元字符
          • 转义
          • 重复
          • 贪婪
          • 选择分支
          • 括号的作用
          • 替换
          • 断言
        • 总结
        相关产品与服务
        云开发 CLI 工具
        云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档