js中的正则表达式

什么是正则表达式

正则表达式是用正则表达式语言创建的,正则表达式语言并不是一种完备的程序设计语言,它甚至算不上是一种能够直接安装并运行的程序。更准确地说,正则表达式语言是内置于其他语言或软件产品的“迷你”语言。正则表达式语言虽然也被称为一种语言,但它与人们对语言的印象相去甚远。

正则表达式经常被简称为模式

定义一个正则表达式

js中的正则表达式用RegExp对象表示,有两种方式创建RegExp对象。

一种是通过一种特殊的直接量语法创建

var pattern = /s$/

另一种是使用RegExp()构造函数

var pattern = new RegExp('s$')

如果需要修饰符

var pattern = /s$/i
var pattern = new RegExp('s$', 'i')

js中的正则表达式语法

js中的正则表达式还是比较弱的,比如不支持后行断言,不支持嵌入条件。

直接量字符

直接量字符包括字面含义的字母和数字、非字母的字符、和一些具有特殊含义的字符,后面两种需要转义。

字符 匹配
字母和数字 自身
\o NUL字符(\u0000)
\t 制表符(\u0009)
\n 换行符(\u000A)
\v 垂直制表符(\u000B)
\f 换页符(\u000C)
\r 回车符(\u000D)
\xnn 由十六进制数nn指定的拉丁字符,例如,\x0A等价于\n
\uxxxx 由十六进制数xxxx指定的Unicode字符,例如\u0009等价于\t
\cX 控制字符^X,例如,\cJ等价于换行符\n

Windows使用\r\n表示文本行结束,Unix、Linux只使用\n表示文本结束。

一些具有特殊含义的字符也需要转义,如下

^ $ . * + ? = ! : | \ / ( ) [ ] { }

字符类

将直接量字符单独放进方括号内就组成了字符类,一个字符类可以匹配它所包含的任意字符。由于某些字符类非常常用,因些在js的正则表达式语法中,使用了特定字符的转义字符来表示它们。

字符 匹配
[…] 方括号内的任意字符
[^…] 不在方括号内的任意字符
. 除换行符和其他Unicode行终止符之外的任意字符
\w 任何ASCII字符组成的单词,等价于[a-zA-Z0-9]
\W 任何不是ASCII字符组成的单词,等价于[^a-zA-Z0-9]
\s 任何Unicode空白符
\S 任何非Unicode空白符
\d 任何ASCII数字,等价于[0-9]
\D 任何非ASCII数字,等价于[^0-9]
[\b] 退格直接量(特例)

重复字符

字符 匹配
{n, m}
{n,}
{n}
? 等价于{0, 1}
+ 等价于{1,}
* 等价于{0,}

非贪婪的重复

默认情况下,正则表达式会尽可能多地匹配(贪婪模式),只需要在重复字符后面添加问号?就可以进行非贪婪模式,如??+?*?{1, 5}?

需要注意的是,不管是贪婪模式还是非贪婪模式,正则表达式总是会寻找字符串中第一个可能匹配的位置,如,对于字符串aaabb/a+b/会匹配aaabb/a+?b/会匹配aaab而不是子串中更短的ab

选择

选择项的尝试匹配次序是从左到右,直到发现了匹配项,如果左边的选择项匹配,就忽略右边的匹配项,如字符串ab/a|ab/匹配的是a

字符 匹配
| 匹配的是该符号左边的子表达式或右边的子表达式

分组和引用

分组形成子表达式

字符 匹配
(…)
(^…) 只分组,不编号,即不能被引用
\n 回溯引用

回溯引用(backreference)允许正则表达式模式引用前面的匹配结果。

锚字符

字符 匹配
^ 字符串的开头
$ 字符串的结尾
\b 单词的边界
\B 非单词边界的位置
(?=p) 正向先行断言,要求接下来的字符都与p匹配,但匹配的结果不包括p
(?!p) 负向先行断言,要求接下来的字符都不与p匹

锚字符是匹配位置的,不匹配任何字符,比如对于字符串abca(?=b)bc可以匹配,但是a(?=b)c不匹配。

修饰符

js支持三个修饰符。

字符 匹配
i
g 执行一个全局匹配,即找到所有的匹配,而不是在找到一个之后就停止
m 多行匹配模式,^匹配一行的开头和字符串的开头,$匹配一行结尾和字符串的结尾

RegExp对象

RegExp对象有5个属性和2个方法:

5个属性

source
    只读,正则表达式的文本
global
    只读,是否带有修改符g
ignoreCase
    只读,是否带有修改符i
multiline
    只读,是否带有修改符m
lastIndex
    可读/写,如果匹配模式带有g,这个属性存储整个字符串下一次检索的开始位置

2个方法

exec()
    如果没有找到任何匹配,则返回null,否则返回一个数组,第一个元素包含的是与正则表达式相匹配的字符串,余下的元素是与圆括号内的子表达式相匹配的子串。
    会忽略g。
test()
    如果匹配则返回true

String中4个支持正则表达式的方法

(1) search

  • 返回第一个匹配的子串的起始位置,如果不匹配则返回-1;
  • 如果参数不是正则表达式,则会先通完RegExp()转换成正则表达式;
  • 不支持全局检索,会忽略g。

    var pattern = /c{2}/
    var str = ‘abcdeccfg’
    console.log(str.search(pattern)) // 5

    // 如果参数不是正则表达式,则会先通完RegExp()转换成正则表达式
    var pattern = ‘c{2}’
    var str = ‘abcdeccfg’
    console.log(str.search(pattern)) // 5

(2) replace

如果replace()的第一个参数是字符串而不是正则表达式,则将直接搜索这个字符串;
如果不带g,则只匹配一次;
第二个参数可以是$加数字,代表对应的子串。

(3) match

如果没有g,则返回结果和exec()一样

var pattern = /h(i)/
var str = 'ahibchhidefhiig'
console.log(str.match(pattern)) // ["hi", "i", index: 1, input: "ahibchhidefhiig"]

如果有g,则返回所有的匹配,但不包括子表达式

// 如果有`g`,则返回所有的匹配,但不包括子串
var pattern = /h(i)/g
var str = 'ahibchhidefhiig'
console.log(str.match(pattern)) // ["hi", "hi", "hi"]

(4) split

console.log('123,456,789'.split(',')) // ["123", "456", "789"]

// 好像会忽略`g`
console.log('123, 456 , 789'.split(/\s*,\s*/)) // ["123", "456", "789"]

你可能感兴趣的:(Web前端)