则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。
搜索模式可用于文本搜索和文本替换。
什么是正则表达式?
正则表达式是由一个字符序列形成的搜索模式。
当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。
正则表达式可以是一个简单的字符,或一个更复杂的模式。
正则表达式可用于所有文本搜索和文本替换的操作。
语法
/正则表达式主体/修饰符(可选)
其中修饰符是可选的。
实例:
var patt = /runoob/i
实例解析:
/runoob/i 是一个正则表达式。
runoob 是一个正则表达式主体 (用于检索)。
i 是一个修饰符 (搜索不区分大小写)。
使用字符串方法
在 JavaScript 中,正则表达式通常用于两个字符串方法 : search() 和 replace()。
search() 方法 用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并返回子串的起始位置。
replace() 方法 用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
search() 方法使用正则表达式
实例
使用正则表达式搜索 "Runoob" 字符串,且不区分大小写:
varstr = "Visit Runoob!"; varn = str.search(/Runoob/i);
输出结果为:
6
search() 方法使用字符串
search 方法可使用字符串作为参数。字符串参数会转换为正则表达式:
实例
检索字符串中 "Runoob" 的子串:
varstr = "Visit Runoob!"; varn = str.search("Runoob");
replace() 方法使用正则表达式
实例
使用正则表达式且不区分大小写将字符串中的 Microsoft 替换为 Runoob :
varstr = document.getElementById("demo").innerHTML; vartxt = str.replace(/microsoft/i,"Runoob");
结果输出为:
Visit Runoob!
replace() 方法使用字符串
replace() 方法将接收字符串作为参数:
varstr = document.getElementById("demo").innerHTML; vartxt = str.replace("Microsoft","Runoob");
正则表达式修饰符
修饰符 可以在全局搜索中不区分大小写:
正则表达式参数可用在以上方法中 (替代字符串参数)。
正则表达式使得搜索功能更加强大(如实例中不区分大小写)。
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配。 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 |
m | 执行多行匹配。 |
正则表达式模式
方括号用于查找某个范围内的字符:
表达式 | 描述 |
---|---|
[abc] | 查找方括号之间的任何字符。 |
[0-9] | 查找任何从 0 至 9 的数字。 |
(x|y) | 查找任何以 | 分隔的选项。 |
元字符是拥有特殊含义的字符:
元字符 | 描述 |
---|---|
\d | 查找数字。 |
\s | 查找空白字符。 |
\b | 匹配单词边界。 |
\uxxxx | 查找以十六进制数 xxxx 规定的 Unicode 字符。 |
量词:
量词 | 描述 |
---|---|
n+ | 匹配任何包含至少一个 n 的字符串。 |
n* | 匹配任何包含零个或多个 n 的字符串。 |
n? | 匹配任何包含零个或一个 n 的字符串。 |
使用 RegExp 对象
在 JavaScript 中,RegExp 对象是一个预定义了属性和方法的正则表达式对象。
使用 test()
test() 方法是一个正则表达式方法。
test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。
以下实例用于搜索字符串中的字符 "e":
实例
var patt = /e/;
patt.test("The best things in life are free!");
字符串中含有 "e",所以该实例输出为:
true
你可以不用设置正则表达式的变量,以上两行代码可以合并为一行:
/e/.test("The best things in life are free!")
使用 exec()
e
击右上方红色按钮关注“web秀”,让你真正秀起来
作为一名程序猿,对正则表达式一定不会很陌生,但在平时开发中有时依然会遇到这样或那样的问题。本文从基础出发,本着让初学者入门,高手温故的初衷,相对系统性的介绍正了则相关知识。如有不准确的地方,欢迎吐槽
本文仅介绍 javascript 语言中的正则,其他语言虽有不同,但很类似,感兴趣的自行google吧。另外本文针对所有示例都给了输出结果,希望读者思考为什么返回这样的结果,和自己期望的有什么不一样,建议自己也动手输入一下,加深记忆。
JavaScript正则表达式详细总结
本文总体分两部分:基础知识 和 案例分析
一、正则申明方式
1、构造函数方式
var reg = new RegExp('\d', 'gi');
JavaScript正则表达式详细总结
说明:
'aBcd efg'.match(/[a-z]+/); // ["a"] 'aBcd efg'.match(/[a-z]+/i); // ["aBcd"] 'aBcd efg'.match(/[a-z]+/g); // ["a", "cd", "efg"] 'aBcd efg'.match(/[a-z]+/gi); // ["aBcd", "efg"] 'aB\ncd\n efg'.match(/^[a-z]+/m); // ["a"] 'aB\ncd\n efg'.match(/^[a-z]+/g); // ["a"] 'aB\ncd\n efg'.match(/^[a-z]+/gm); // ["a", "cd"] // 注意不是 ["a", "cd", "efg"]
具体用法请看下文相关的示例
2、字面量方式
相比较上一种方式,这一种更为常见,上面示例也都使用了这种方式
var reg = /\d/gi;
两个斜线内为正则的内容,后面可以跟修饰符,与第一种构造函数方式相比更简洁,缺点是正则内容不能拼接,对于大多数场景俩说足够了
二、正则相关符号
1、方括号 [] 用法
用于查找方括号内的任意字符:
JavaScript正则表达式详细总结
注意:
1)^ 在 [] 内开始位置及正则双斜线开始位置有特殊含义,其他位置表示 ^ 字符本身
'adobe 2016'.match(/^[a-zA-Z]+/); // ["adobe"]
'adobe2016ps'.match(/\d+|^[a-z]+/g); // ["adobe", "2016"]
'adobe'.match(/[^abc]/g); // ["d", "o", "e"]
注: $ 与 ^ 的前两个用法相似,只不过匹配的是以某某字符结尾的字符串,举例:
'adobe 2016'.match(/\d+|[a-z]+$/g); // ["2016"] 'adobe'.match(/\d+|[a-z]+$/g); // ["adobe"]
2)- (连字符)表示左边字符的 ASCII 值到右边字符 ASCII 编码值之间及左右字符自身的所有字符
'adobe PS 2016'.match(/[a-g]/g); // ["a", "d", "b", "e"]
3)- 连字符左侧的字符对应的 ASCII 值一定要小于或等于右侧的字符,否则会报语法错误
'adobe'.match(/[z-a]/); // Uncaught SyntaxError: Invalid regular expression: /[z-a]/: Range out of order in character class...
4)如果希望对连字符 - 本身进行匹配,需要用反斜线转义
'adobe-2016'.match(/[a-g\-]/g); // ["a", "d", "b", "e", "-"]
5)查看 ASCII 表就会发现,大写字母的 ASCII 值是小于小写字母的,因此下面用法会报语法错误
'adobe-2016'.match(/[a-Z]/g); // Uncaught SyntaxError: Invalid regular expression: /[a-Z]/: Range out of order in character ...
那么问题来了,如果要表示所有字母,不区分大小写怎么办呢?其实有两种方式:
A、第一种是使用修饰符 i,前面提到过。举例:
'adobe-PS'.match(/[a-z]/gi); // ["a", "d", "o", "b", "e", "P", "S"]
B、第二种是在正则中明确指明大小写字母,举例:
'adobe-PS'.match(/[a-zA-Z]/g); // ["a", "d", "o", "b", "e", "P", "S"]
返回结果跟第一种一样。当然这个例子有些特殊:匹配了所有大小写字母。当只匹配部分大小写字母的时候只能使用第二种方式,在此就不做示例了,读者可以自己测试
6)匹配大小字母不能写成 [A-z],虽然不会报语法错误,但隐式的放大了匹配范围,查看 ASCII 会发现,在大写字母 Z 到小写字母 a 之间还有 [、 \、 ]、 ^、 _、 ` 这6个字符,因此不能这么写。
7)想必有同学会问, \w 不也可以匹配字母么?是的,\w 确实可以匹配字母,但跟上面说的一样,也隐式的放大了匹配范围,\w 除了匹配大小字母外还匹配了数字和下划线,即 \w 与 [A-Za-z0-9_] 等价,当然 A-Z、a-z、0-9(等价于\d)、_这四组没顺序之分
2、特殊含义字符
'1+0.2*2=1.4'.match(/.{2}/g); // ["1+", "0.", "2*", "2=", "1."]
'ad34~!@$ps'.match(/\w/g); // ["a", "d", "3", "4", "p", "s"]
'ad34~!@$ps'.match(/\W/g); // ["~", "!", "@", "$"]
'ps6'.match(/\d/g); // ["6"]
'ps6'.match(/\D/g); // ["p", "s"]
'adobe ps'.match(/\s/g); // [" "]
'adobe ps'.match(/\S/g); // ["a", "d", "o", "b", "e", "p", "s"]
'adobe(2016) ps6.4'.match(/\b(\w+)/g); // ["adobe", "2016", "ps6", "4"]
'adobe(2016) ps6.4'.match(/\B(\w+)/g); // ["dobe", "016", "s6"]
'\0'.match(/\0/); // ["NUL"]
'adobe\nps'.match(/\n/).index; // 5
'adobe\fps'.match(/\f/).index; // 5
'adobe\rps'.match(/\r/).index; // 5
'adobe\tps'.match(/\t/).index; // 5
'adobe\vps'.match(/\v/).index; // 5
'a'.charCodeAt(0).toString(8); // "141" 'adobe ps'.match(/\141/g); // ["a"]
'a'.charCodeAt(0).toString(16); // "61" 'adobe ps'.match(/\x61/g); // ["a"]
'a'.charCodeAt(0).toString(16); // "61" 'adobe ps'.match(/\u0061/g); // ["a"]
注意:
window系统回车换行符为\r\n,linux系统下没有\r,linux系统通过vi编辑器打开window系统的文本文件时候,经常在行尾出现^M符号,也就是\r的原因,解析文本的时候需要注意相关判断。
3、量词说明
'adobe paas'.match(/a+\w+/g); // ["adobe", "aas"]
'ab3 aa12bb'.match(/a*\d+/g); // ["3", "aa12"]
'ab3 aa12bb'.match(/a?\d+/g); // ["3", "a12"]
'ab3 aa12bb aaa34'.match(/a{2}\d+/g); // ["aa12", "aa34"]
'a3 aaa12bb aaaaaaa34'.match(/a{2,4}\d+/g); // ["aaa12", "aaaa34"]
'a3 aaa12bbaa4'.match(/a{2,}\d+/g); // ["aaa12", "aa4"]
由上可知,以下 表达式1 与 表达式2 等价
JavaScript正则表达式详细总结
4、符号说明
符号 {}、^、$、*、+、?、[]、[^]、- 已经在前面介绍过,接下来看下其他特殊字符
'adobe ps13'.match(/([a-g]+l\d+)/g); // ["ad", "be", "13"]
'adobe'.match(/\w+/); // ["adobe"]
'a\\dobe'.match(/\\/); // ["\"]
5、小括号 () 用法
正则在非全局(g)模式下,通过match方式,返回的数组第一个值整体匹配的字符串,其他值为通过括号分组匹配到的
1)捕获用法
'adobe cs9cs10, adobe cs11'.match(/([a-z]+\d+)+/); // ["cs9cs10", "cs10"] // 注意{2,}是对 括弧内的匹配 的描述
"he is 12. she is 13. it's box".match(/(it|she|he)\s+is/g); // ["he is", "she is"]
'adobe cs9'.match(/[a-z]+\d+/); // ["cs9"] 'adobe cs9'.match(/[a-z]+(\d+)/); // ["cs9", "9"]
引用的结果可以通过 构造函数 RegExp 获取,即 RegExp.一直到 RegExp.
'Can you can a can as a canner can can a can?'.match(/([cC]an+)\s+\1/g); // ["can can"] // 注意 `\1` 等价于正则里的 `([a-z]+)`,即与下面示例相同 'Can you can a can as a canner can can a can?'.match(/[cC]an+\s+[cC]an+/g); // ["can can"] // 如果把括弧去掉可以看下结果 'Can you can a can as a canner can can a can?'.match(/[cC]an+\s+\1/g); // null
2)非捕获用法,以(?)形式出现
// 不使用括号时 'adobe12ps15test'.match(/[a-z]+\d+[a-z]+/); // ["adobe12ps"] // 使用括号分组 'adobe12ps15test'.match(/[a-z]+(\d+)([a-z]+)/); // ["adobe12ps", "12", "ps"] 'adobe12ps15test'.match(/[a-z]+(?:\d+)([a-z]+)/); // ["adobe12ps", "ps"] // 看起来上面语句不用(?:)也可以得到相同结果,即: 'adobe12ps15test'.match(/[a-z]+\d+([a-z]+)/); // ["adobe12ps", "ps"] // 注意,但需求希望匹配字母之间的规则复杂时,如希望匹配字母,且字母之间可以为1或3时,但不需要1和3 'adobe11ps15test'.match(/[a-z]+(1|3)+([a-z]+)/); // ["adobe11ps", "1", "ps"] // 返回中不希望包含数字怎么办,可以使用非捕获 'adobe11ps15test'.match(/[a-z]+(?:1|3)+([a-z]+)/); // ["adobe11ps", "ps"]
'adobe12ps15test'.match(/[a-z]+(?=\d)/g); // ["adobe", "ps"]
'adobe12ps15test'.match(/[a-z]+(?!\d)/g); // ["adob", "p", "test"]
'adobe12ps15test'.match(/(?<=\d)[a-z]+/g); // ["ps", "test"]
'adobe12ps15test'.match(/(?<!\d)[a-z]+/g); // ["adobe", "s", "est"]
3)注意
'11+2=13'.match(/\d+\+/g); // ["11+"] '(11+2)*2=26'.match(/\(\d+\+\d+\)/g); // ["(11+2)"]
// 注意下面两个表达式返回的结果 'path C:\Windows\System32'.match(/([a-zA-Z]:\\\w+)/g); // null 'path C:\\Windows\\System32'.match(/([a-zA-Z]:\\\w+)/g); // ["C:\Windows"]
说明:
在申明字符串 'path C:\Windows\System32' 时,其中的 '' 就已经被当做转移符,既是 '\W' === 'W',所以如果希望申明的字符串中包含反斜线,需要在加一个反斜线转义,即 \
6、正则相关方法
1) RegExp对象相关方法
JavaScript正则表达式详细总结
2)String对象相关方法
JavaScript正则表达式详细总结
3)replace 具体用法
顾名思义,是字符串替换方法,但用法比较广泛,相信读者已经非常熟悉了。在此就当复习了
A、 基本用法
直接传入字符串进行替换,找到子串后只替换一次,举例:
'adobe abc'.replace('b', '_') // "ado_e abc" // 注意 第二个 b 没有被替换
如果希望全部替换,可以使用正则表达式并用全局修饰符 g 方式,举例:
'adobe abc'.replace(/b/g, '_') // "ado_e a_c"
B、 高级用法
第二个参数可以使用 function,其中有三个参数,分别为 匹配的字符串、当前匹配的字符串index值、匹配的源字符串,最终结果根据每次匹配结果进行相应的替换
举例:
'adobe aacc bbaa'.replace(/a+/g, function(str, index, source){ if(index > 0){ return str.toUpperCase(); } else { return str; } }); // "adobe AAcc bbAA"
一、常见匹配
在写正则之前,需要注意以下几点:
1、手机号
规则:以1开头第二位为3、5、7、8且长度为11位的数字组合
/^1[3578]\d{9}$/.test(13600001111); // true
2、 字符串提取
举例:提取字符串中的数字
分析:
根据对数字的理解,可能为负数,即-?,如果是负数,其后需要是数字且至少一位,即 -?\d+,小数部分可能有也可能没有,所以需要对小数部分括弧起来用 ? 或 {0, 1}限定,因为.是特殊字符需要转义,于是表达式为:-?\d+(\.\d+)?
'(12.3 - 32.3)*2 = -40'.match(/-?\d+(\.\d+)?/g); // ["12.3", "32.3", "2", "-40"]
二、jQuery中的正则片段
1、表达式
在jQuery 3.1.2-pre中找到一个解析单标签的正则,如下:
/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i
2、分解
乍一看有点懵,其实拆解之后就容易理解了,注意拆解的步骤,通常来说:
1) 第一步可以先看括号 () ,可以将各个小括号及非括号的分成不同部分,如
/^< ([a-z][^\/\0>:\x20\t\r\n\f]*) [\x20\t\r\n\f]*\/?> (?:<\/\1>|) $/i
2) 第二步可以将中括号分开
/^< ( [a-z] [^\/\0>:\x20\t\r\n\f]* ) [\x20\t\r\n\f]* \/?> (?:<\/\1>|) $/i
现在是不是已经很清楚了,接下来分解下,就很容易理解了
3、详解
喜欢小编的点击关注,了解更多知识!
者:徐小夕
转发链接:https://mp.weixin.qq.com/s/2Bk8lkRCNyaTWYtIB0oYVg
*请认真填写需求信息,我们会在24小时内与您取得联系。