正则表达式定义
正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是一种强大而灵活的文本处理工具,用于文本的复杂处理,常用的应用场景如字符串的搜索,匹配,替换等。大部分的编程语言,脚本语言或文本编辑器都支持正则表达式,虽然在用法上有些许差异,但是语法规则都是类似的。学习正则表达式就是学习其语法规则,然后运用这些规则去匹配需求的字符串。
学习目的
由于正则表达式的强大而灵活的功能,在项目中会经常使用到,由于前后端程序分离开发,后端开发的接口不信任前端送过来的数据是正确的,后端需要数据校验,但是为了响应效率,无疑在前端做数据校验是必要的。所以通常前后端都做数据校验,数据校验通常是判空,判断数据格式之类的,后者就需要使用到正则表达式了。当然,这只是正则表达式用途之一,也可用于数据库SQL,linux文件中的vim操作、文件查找,所以学习正则表达式还是很有必要的。
正则表达式语法
语法规则比较多,只要求记住常用的就行,如果忘记可以查找相关资料。总体来说分为普通字符和元字符(特殊字符),细分为以下几类。
1. 普通字符
字母、数字、汉字、下划线以及没有特殊定义的标点符号,都是普通字符。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。
2. 简单的转义字符
表达式 | 作用 |
---|---|
\n | 代表换行符 |
\t | 制表符 |
\^ \$ \. \{ \+等 | 代表字符本身 |
3.标准字符集合
- 能和多种字符匹配
- 区分大小写,大写是相反意思
表达式 | 作用 |
---|---|
\d | 任意一个数字,0-9中任意一个 |
\w | 任意一个字母或数字或下划线也就是A-Z,a-z,0-9,_任意一个 |
\s | 包括空格、制表符、换行符等空白字符的其中任意一个 |
. | 小数点可以匹配任意一个字符(除了换行符),如果匹配要包括换行符之内的所有字符,一般用[\s\S] |
4.自定义字符集合
- [ ]方括号匹配方式,能够匹配方括号中任意一个字符
- 正则表达式中的特殊符号,如果是包含于中括号内,则失去特殊含义,除了^之外(表示取反)
- 标准字符集合,除了小数点外,如果是包含于中括号内,自定义字符集合将包含该集合
5.限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。
表达式 | 作用 |
---|---|
* | 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \* |
+ | 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+ |
? | 匹配前面的子表达式零次或一次。要匹配 ? 字符,请使用 \? |
{n} | n 是一个非负整数。匹配确定的 n 次。 |
{n,} | n 是一个非负整数。至少匹配n 次。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。 |
限定符也叫量词,是修饰匹配次数的特殊符号。
匹配字数的两种模式
- 贪婪模式(默认)
匹配字符按照最大的可匹配数量匹配
- 非贪婪模式
匹配字符按照最少可匹配的数量匹配,在限定符后加个?号即表示非贪婪模式
6.定位符
定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。
表达式 | 作用 |
---|---|
^ | 字符串的开始 |
$ | 字符串的结束 |
\b | 描述字符串的前或后边界 ,前面和后面的字符不全是\w |
\B | 表示字符串边界,\b取反的情况 |
7.选择符和分组
表达式 | 作用 |
---|---|
| | 左右两边表达式之间“或关系 |
() | 用圆括号将所有选择项括起来,使相关的匹配会被缓存 |
(?:表达式) | 需要使用分组形式,但是不需要保存分组中匹配的内容时使用 |
8.反向引用
- 每一对()会分配一个编号,使用()的捕获根据左括号的顺序从1开始自动编号。
- 通过反向引用,可以对分组已捕获的字符串进行引用
9.匹配模式
- 单行模式
每一行都有开头和结尾 - 多行模式
整个文本只有一个开头一个几位 - 忽略大小写(默认区分)
这三个匹配模式可以在定义正则表达式时候通过设定参数设置。
正则表达式使用实例
需求:需要完成一个页面选择本地文件,上传到服务器,分别在前后端校验文件类型(图片.jpg或者.png),如果上传类型错误,则提示错误。
正则表达式:.+(\.png|\.jpg|\.PNG|\.JPG)
.+匹配文件主名,分组内匹配文件扩展名,即文件后缀。
先上代码
- 前端js校验
str = "";//待匹配字符串
var pattern = /.+(\.png|\.jpg|\.PNG|\.JPG)/;
console.log(pattern.test(str));
- 后端java校验
String str = "";//待匹配字符串
String pattern = ".+(\\.png|\\.jpg|\\.PNG|\\.JPG)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(str);
System.out.println(m.matches());
可以看出来js和Java在正则表达式的使用上还是有差异的(在慢慢的学习过程中发现,JS和Java完全是没有一毛钱关系的两种语言,但是由于语法有一定的相似性,导致很多时候把两者弄混淆了),导致每次正则写的就很烦,老是通过不了。
这是因为js里面使用的是RegExp 对象表示正则表达式,js的var变量定义是泛类型的,所以可以直接量语法定义一个RegExp对象,只要用var regex = /正则表达式字符串/
,即可用该对象使用正则表达式的功能。
所以上述js代码也可以改为:
str = "";//待匹配字符串
//var pattern = /.+(\.png|\.jpg|\.PNG|\.JPG)/;
var regexp= new RegExp(".+(\.png|\.jpg|\.PNG|\.JPG)");
console.log(regexp.test(str));
实现的是一模一样的功能呀。
而java只能定义一个正则表达式字符串,然后利用Pattern和Matcher配合使用正则表达式,这两个类是java.util.regex是一个用于正则表达式匹配工作的两个重要类库包,还有其他几个类,之后再细细研究。
通过查看javaAPI,这两个类的解释分别为:
- Pattern 正则表达式的编译表示。
正则表达式,指定为一个字符串,必须首先被编译为这个类的一个实例。然后得到的模式可以用来创建一个Matcher对象可以匹配任意字符序列与正则表达式。 - Matcher 匹配器,是通过调用模式的matcher方法从模式创建。
通过解释模式引擎在字符序列中执行匹配操作。
大概意思就是Pattern类用于构造正则表达式,Matcher类是匹配器,做匹配操作。
JS和JAVA中如何使用正则表达式做更多的操作这里就不再详细说明,可以查看文档使用,这里主要目的是区分js和Java使用正则表达式的差异,避免之后再弄混淆,这也是写该文章的主要目的。
正则表达式测试
一般来说,使用正则表达式有3个步骤,第一步准备好待匹配数据,第二步写正则表达式验证测试,第三步在程序中调试。要是对正则表达式足够熟练,直接跳到第三步也未尝不可,通常复杂点的正则表达式是先要验证测试然后再用到程序中的。这里介绍一下测试方法。
正如前面所提及的正则表达式的强大和广泛应用,所以要验证测试正则表达式的方法也是多种多样的,介绍一下自己平时常用的几种测试方式。
-
html使用
<html> <body> <script type="text/javascript"> str = "aa.png";//待匹配字符串 //var pattern = /.+(\.png|\.jpg|\.PNG|\.JPG)/; var regexp= new RegExp(".+(\.png|\.jpg|\.PNG|\.JPG)"); alert(regexp.test(str)); </script> </body> </html>
-
文本编辑器中使用(EditPlus,UltraEdit,Sublime Text等,感觉最方便)
ctrl+f 弹出搜索框,选中Regular expression -
在线测试工具
推荐菜鸟工具正则表达式在线测试,该页面能根据正则表达式自动生成js,java,python等代码,简直不要太好用,但是在学习阶段建议自己写。此外还有常用的一些正则表达式可供参考。