正则表达式入门

以下内容借鉴菜鸟教程中的正则表达式部分。

1、概念

正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。它是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,它的功能非常强大。许多程序设计语言都支持利用正则表达式进行字符串操作,比如Java。

通过一个例子进行测试:
在这里插入图片描述
在这里插入图片描述
这个正则匹配到了数字。

2、简介

简单示例:
在这里插入图片描述
说明:

  • ^为匹配输入字符串的开始位置。
  • [0-9]+匹配多个数字, [0-9]匹配单个数字,+匹配一个或者多个。
  • abc$匹配字母abc并以abc结尾,$为匹配输入字符串的结束位置。

测试:
在这里插入图片描述
在这里插入图片描述
另一个示例:
在这里插入图片描述
测试:
在这里插入图片描述
在这里插入图片描述

2.1、发展历史

正则表达式的"祖先"可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch 和 Walter Pitts 这两位神经生理学家研究出一种数学方式来描述这些神经网络。1956年, 一位叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上,发表了一篇标题为"神经网事件的表示法"的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为"正则集的代数"的表达式,因此采用"正则表达式"这个术语。

随后,发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究,Ken Thompson 是 Unix 的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器。如他们所说,剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。

2.2、正则的用途

典型的搜索和替换操作要求您提供与预期的搜索结果匹配的确切文本。虽然这种技术对于对静态文本执行简单搜索和替换任务可能已经足够了,但它缺乏灵活性,若采用这种方法搜索动态文本,即使不是不可能,至少也会变得很困难。

通过使用正则表达式,可以:

  • 测试字符串内的模式:例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。
  • 替换文本:可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。
  • 基于模式匹配从字符串中提取子字符串:可以查找文档内或输入域内特定的文本。

2.3、正则的应用范围

目前,正则表达式已经在很多软件中得到广泛的应用,包括 *nix(Linux, Unix等)、HP 等操作系统,PHP、C#、Java等开发环境,以及很多的应用软件中,都可以看到正则表达式的影子。作为Java后端开发人员,应该熟悉Java中正则表达式的应用。

3、语法

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

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

示例:

  • fanren+ycz+表示前面的字符至少出现1次。那么这个表达式可以匹配fanrenycz、fanrennnnycz等。
  • fanren*ycz*表示前面的字符可以出现任意次数(包括0次)。那么这个表达式可以匹配fanreycz、fanrenycz、fanrennnycz等。
  • fanren?ycz?表示前面的字符至多出现1次。那么这个表达式可以匹配fanreycz、fanrenycz这两个。

测试:
在这里插入图片描述
在这里插入图片描述

3.1、普通字符

普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试:

<script>
	// 匹配[]里面的所有字符
	var p1 = /[ycz]/g;
	var s1 = "yanchengzhi";
	document.write(s1.match(p1) + "<br/>");
	// 匹配[]之外的所有字符
	var p2 = /[^ycz]/g;
	var s2 = "yanchengzhi";
	document.write(s2.match(p2) + "<br/>");
	// 只匹配大写字母
	var p3 = /[A-Z]/g;
	var s3 = "YANchengzhi";
	document.write(s3.match(p3) + "<br/>");
	// 只匹配小写字母
	var p4 = /[a-z]/g;
	var s4 = "YANchengzhi";
	document.write(s4.match(p4) + "<br/>");
	// 只匹配数字
	var p5 = /[0-9]/g;
	var s5 = "YANchengzhi0918";
	document.write(s5.match(p5) + "<br/>");
	// 匹配除了换行符\n、\r之外的所有字符,包括空白符
	var p6 = /./g;
	var s6 = "YAN \ncheng\n zhi\r 0918";
	document.write(s6.match(p6) + "<br/>");
	// 匹配所有字符,包括换行符\n、\r
	var p7 = /[\s\S]/g;
	var s7 = "YAN \ncheng\n zhi\r 0918";
	document.write(s7.match(p7) + "<br/>");
	//匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
	var p8 = /[\w]/g;
	var s8 = "(YAN) \ncheng-\n zhi*\r _+0918";
	document.write(s8.match(p8) + "<br/>");	
</script>

在这里插入图片描述

3.2、非打印字符

非打印字符也可以是正则表达式的组成部分。下表列出了表示非打印字符的转义序列:
在这里插入图片描述

3.3、特殊字符

特殊字符,就是一些有特殊含义的字符,如*,简单的说就是表示任何字符串的意思。如果要查找字符串中的*符号,则需要对*进行转义,即在其前加一个\,即\*

许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\放在它们前面。下表列出了正则表达式中的特殊字符:
在这里插入图片描述

3.4、限定字符

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 *+?{n}{n,}{n,m}共6种。

正则表达式的限定符有:
在这里插入图片描述
测试:
在这里插入图片描述
在这里插入图片描述
注意:限定符出现在范围表达式之后,它应用于整个范围表达式。

贪婪:下面的表达式匹配从开始小于符号 (<) 到大于符号 (>) 之间的所有内容。
在这里插入图片描述
在这里插入图片描述
*+ 限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配。

修改测试:
在这里插入图片描述
在这里插入图片描述
它只匹配到了第一个标签的开始标签内容,即<a href='http://www.baidu.com'>
在这里插入图片描述
在这里插入图片描述

3.5、定位符

定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。

定位符用来描述字符串或单词的边界,^$ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。

正则表达式的定位符有:
在这里插入图片描述
注意事项:

  • 不能将限定符与定位符一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。
  • 若要匹配一行文本开始处的文本,请在正则表达式的开始使用 ^ 字符。不要将 ^ 的这种用法与中括号表达式内的用法混淆。
  • 若要匹配一行文本的结束处的文本,请在正则表达式的结束处使用 $ 字符。
  • 单词边界是单词和空格之间的位置。非单词边界是任何其他位置。

测试:
在这里插入图片描述
在这里插入图片描述

3.6、选择

用圆括号 () 将所有选择项括起来,相邻的选择项之间用 | 分隔。() 表示捕获分组,() 会把每个分组里的匹配的值保存起来, 成为数组中的元素。多个匹配值可以通过数字 n 来查看(n 是一个数字,表示第 n 个捕获组的内容)。

测试:
在这里插入图片描述
在这里插入图片描述
圆括号会有一个副作用,使相关的匹配会被缓存,此时可用 ?: 放在第一个选项前来消除这种副作用。其中 ?: 是非捕获元之一,还有两个非捕获元是 ?=?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。

部分规则如下:

  • exp1(?=exp2):查找 exp2 前面的 exp1。
  • (?<=exp2)exp1:查找 exp2 后面的 exp1。
  • exp1(?!exp2):查找后面不是 exp2 的 exp1。
  • (?<!exp2)exp1:查找前面不是 exp2 的 exp1

测试:
在这里插入图片描述
在这里插入图片描述

3.7、反向引用

对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从1开始,最多可存储99个捕获的子表达式。每个缓冲区都可以使用 \n 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。

可以使用非捕获元字符 ?:?=?! 来重写捕获,忽略对相关匹配的保存。反向引用的最简单的、最有用的应用之一,是提供查找文本中两个相同的相邻单词的匹配项的能力。

测试:
在这里插入图片描述
在这里插入图片描述
说明:

  • 捕获的表达式为[a-z]+ 指定的,包括一个或多个字母。
  • 第二部分是对以前捕获的子匹配项的引用,单词的第二个匹配项正好由括号表达式匹配,\1 指定第一个子匹配项。
  • 单词边界元字符\b确保只检测整个单词。
  • g指定将该表达式应用到输入字符串中能够查找到的尽可能多的匹配。
  • i 标记指定不区分大小写。

反向引用还可以将通用资源指示符 (URI) 分解为其组件。如下:
在这里插入图片描述
在这里插入图片描述
说明:

  • 第一个括号子表达式捕获 Web 地址的协议部分。该子表达式匹配在冒号和两个正斜杠前面的任何单词。
  • 第二个括号子表达式捕获地址的域地址部分。子表达式匹配非 : 和 / 之后的一个或多个字符。
  • 第三个括号子表达式捕获端口号(如果指定了的话)。该子表达式匹配冒号后面的零个或多个数字。只能重复一次该子表达式。
  • 第四个括号子表达式捕获 Web 地址指定的路径和 / 或页信息。该子表达式能匹配不包括 # 或空格字符的任何字符序列。

3.8、修饰符(标记)

标记也称为修饰符,正则表达式的标记用于指定额外的匹配策略。标记不写在正则表达式里,标记位于表达式之外。

格式:

/pattern/flags

说明:pattern为表达式,flags为标记。

正则中的常用标记:
在这里插入图片描述
测试:
在这里插入图片描述
在这里插入图片描述

3.9、元字符

下表包含了元字符的完整列表以及它们在正则表达式上下文中的行为:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以下测试匹配一个邮箱。
在这里插入图片描述
测试:
在这里插入图片描述
在这里插入图片描述
注意:理解单词边界\b的含义,\b并不是指空格,而是指空格与字符之间或者字符与空格之间的部分。像上面的例子,开头就是\b,那么空格之前的aweq包括一个空格就排除了,结尾也是一个\b,那么空格之后的1721gs包括一个空格也就排除了,只剩下中间的部分。

3.10、运算符的优先级

正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。相同优先级的从左到右进行运算,不同优先级的运算先高后低。

下表的运算符的优先级从高到低:
在这里插入图片描述

3.11、匹配规则

3.11.1、基本模式匹配

基本模式是最基本的匹配规则,如下:

// 只匹配以word开头的串
^word
// 只匹配以word结尾的串
word$
// 以word开头或结尾的串都匹配
^word$
// 包含word的串都匹配
word
// 匹配以换行符开头的串
^\n
// 匹配以制表符开头的串
^\t
// 匹配以空格开头的串
^\s

测试:
在这里插入图片描述
在这里插入图片描述

3.11.2、字符簇

在INTERNET的程序中,正则表达式通常用来验证用户的输入。当用户提交一个FORM以后,要判断输入的电话号码、地址、EMAIL地址、信用卡号码等是否有效,用普通的基于字面的字符是不够的。所以要用一种更自由的描述我们要的模式的办法,它就是字符簇。要建立一个表示所有元音字符的字符簇,就把所有的元音字符放在一个方括号里。

如下:

// 只匹配a、b、c字符
[abc]
// 只匹配以a、b、c字符开头的
^[abc]
// 只匹配a、b、c字符之外的字符
[^abc]
// 只匹配小写字母
[a-z]
// 只匹配大写字母
[A-Z]
// 只匹配字母
[a-zA-Z]
// 只匹配数字
[0-9]
// 只匹配数字或点或减号
[0-9\.\-]

测试:
在这里插入图片描述
在这里插入图片描述

3.11.3、确定重复出现

大多数情况下都不是匹配单个字符,而是匹配一个长串。
在这里插入图片描述
在这里插入图片描述
另一种写法:
在这里插入图片描述

4、小结

正则表达式还是比较复杂的,字符比较多,含义也不一样,更重要的是灵活多变的组合模式,学好正则有难度,一个比较长的正则表达式往往会看的眼花缭乱,不过它是一个非常有用的东西,无论对于前端还是后端来说,掌握熟悉正则表达式的用法可以让我们事半功倍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值