[转]阿里程序员带你全面深入了解正则表达式

jackxiang 2018-12-23 13:46 | |
附常用工具:

在线正则测试:http://tool.oschina.net/regex/

生成正则图片:https://regexper.com

==================================
在日常工作中,经常会用到正则操作。但是对于大多数人来说,操作正则表达式简直就是抓瞎。

本篇文章主要整理了正则表达式匹配的规则,使用中的一些要点,以及用图形化的方式列举出一些常见的正则表达式,希望能给大家带来一定的帮助,能在以后的工作中,用上正则,爱上正则。

PS:不同语言中的正则表达式的规则不完全相同,但是大部分都可以适用。

正则是什么
正则表达式是为了对字符串进行有效 数据提取 以及 匹配 的一种机制,字符串在匹配的过程中将会从第一个位置开始匹配,然后从左往右进行依次匹配,每尝试匹配一次,就会把控制权交由下一个位置,直到匹配结束。

正则表达式是由 普通字符(例如字符 a 到 z)以及 特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

正则的诞生
正则表达式的“祖先”可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch 和 Walter Pitts 这两位神经生理学家研究出一种数学方式来描述这些神经网络。

1956 年, 一位叫 Stephen Kleene 的美国数学家在 McCulloch 和 Pitts 早期工作的基础上,发表了一篇标题为「神经网事件的表示法」的论文,引入了正则表达式的概念。

正则表达式就是用来描述他称为“正则集的代数”的表达式,因此采用“正则表达式”这个术语。

随后,人们发现可以将这一工作应用于使用Ken Thompson 的计算搜索算法的一些早期研究,Ken Thompson是Unix 的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的qed 编辑器。从那时起直至现在正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。具有完整语法的正则表达式使用在字符的格式匹配方面上,后来被应用到熔融信息技术领域。自从那时起,正则表达式经过几个时期的发展,现在的标准已经被ISO(国际标准组织)批准和被Open Group组织认定。

匹配规则
下面将正则中的一些基本的匹配规则列出来如下表所示:



要点
贪与不贪
举个例子,假设有以下这段html字符,我想拿到a标签中的内容:

<a>
南京长江大桥
</a>
哈哈
<a>
南京市长江大桥
</a>

然后我写了这样一个正则: <a>(.)*</a>

在线测试的结果如下(注意:这个点包起来,*没有包起来):
<a>1212</a><a>2222</a>

这个结果与我们的预期不符,正常我应该得到两个匹配的结果才对,但是现在却只匹配到一个结果。

现在把刚刚的正则改成这样: <a>(.)*?</a>

在线测试的结果如下:
共找到 2 处匹配:
<a>1212</a>
<a>2222</a>

贪 说的是正则在不约束的情况下会继续自动向右进行匹配,直到匹配结束,只要匹配的数据与正则的最后一个值匹配就算是匹配到了。

不贪 说的是只要匹配到就结束,不继续向右进行匹配了。

问号 ? 就解决了贪婪的问题,使得问号前面的字符匹配到之后就结束,但是并不是把 ?放在哪里都可以解决贪婪的,在正则里,有一些属于贪婪模式量词,比如以下这些:

{m,n}

{m,}

?

*

+

断言与零宽
在java中我们知道 断言 可以用来声明一个应该为 true 的事实,只有当断言为真时才会继续进行后续的操作。

在正则中也有 断言 的概念,但是在正则中除了 断言 还有 零宽 的概念。

断言:

通俗点将断言就是 “我断定某某情况是真的” ,而正则中的断言,就是说正则可以断定在 指定的内容 的 前面 或 后面 会出现满足指定规则的内容。比如 "aa1bb2cc3",正则可以用断言找出 bb2 前面有 aa1,也可以找出 bb2 后面有 cc3。

零宽:

零宽就是没有宽度,在正则中,断言只是匹配位置,不占字符,也就是说,匹配结果里是不会返回断言本身的。

断言一共有四种情况:

<span class="read-cnt">阅读数:1024</span>

\d+(?=</span>)
分组
正则表达式中用小括号 () 来做分组,也就是括号中的内容作为一个整体。

因此当我们要匹配分组 he 的时候,可以用下面这个表达式 :

(he)

he is a great man,she is a greate woman

(he)

共找到 2 处匹配:
he
he

我们看到正则表达式用小括号来做分组,那么问题来了:

如果要匹配的字符串中本身就包含小括号,那应该怎么办?

针对这种情况,正则提供了转义的方式,也就是要把这些元字符、限定符或者关键字转义成普通的字符,做法很简单,就是在要转义的字符前面加个斜杠(\)即可。

因此当我们要匹配分组 (he) 的时候,可以用下面这个表达式 :
(he) is a great man,(she) is a greate woman
(\(he\))
共找到 1 处匹配:
(he)


aa122bb233cc344
(\w)(\w)\2

共找到 3 处匹配:
122
233
344








From:
https://mp.weixin.qq.com/s/9zdQYSkZdcbWioDECwz56g

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/10002/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!

评论列表
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]