再次学习JS正则表达式


(1)JavaScript通过内置对象RegExp支持正则表达式,两种方法实例化RegExp对象
字面量和构造函数
//字面量方式:
var reg = /\bis\b/
var text = 'He is a boy.'

var result = text.replace(reg, 'IS')    // 'He IS a boy.'

//构造函数
var reg = new RegExp('\\bis\\b', 'g')//注意这个写法, new RegExp('\bis\b', 'g')这样写会报错
var text = 'He is a boy. It is a dog'

var result = text.replace(reg, 'IS')    // 'He IS a boy. It IS a dog'

注:正如不推荐使用new Array而是使用[]创建数组一样,推荐使用字面量创建RegExp对象实例。

(2)修饰符:
g:global 全文搜索

i:ignore case 忽略大小写

m:multiple lines 多行搜索

(3)元字符和字符类
元字符:元字符是在正则表达式中有特殊含义的非字母字符,如\b代表单词边界,可以是单词的开头或结尾。
字符类:很多时候,我们不想匹配某个字符,而想匹配某类字符。此时,我们可以使用元字符[]来构建一个简单的类。

字符类包括简单类,反向类,范围类,组合类,预定义类
//简单类  
var re = /[abc123]/;//将匹配abc123这6个字符中一个  
//负向类  
re = /[^abc]/;//将匹配除abc之外的一个字符  
//范围类  
re = /[a-b]/;//将匹配小写a-b 26个字母  
re = /[^0-9]/;//将匹配除0-9 10个字符之处的一个字符  
//组合类  
re = /[a-b0-9A-Z_]/;//将匹配字母,数字和下划线 

(4)预定义类和边界

(5)量词(下表量词单个出现时皆是贪婪量词)

(6)贪婪量词与惰性量词 

•用贪婪量词进行匹配时,它首先会将整会字符串当成一个匹配,如果匹配的话就退出,如果不匹配,就截去最后一个字符进行匹配,如果不匹配,继续将最后一个字符截去进行匹配,直到有匹配为止。直到现在我们遇到的量词都是贪婪量词 
•用惰性量词进行匹配时,它首先将第一个字符当成一个匹配,如果成功则退出,如果失败,则测试前两个字符,依些增加,直到遇到合适的匹配为止 

惰性量词仅仅在贪婪量词后面加个"?"而已,如"a+"是贪婪匹配的,"a+?"则是惰性的 

var str = "abc";  
var re = /\w+/;//将匹配abc  
re = /\w+?/;//将匹配a 

(7)分组与非捕获性分组 (也叫忽略分组)

有时候会想要匹配一串字符串连续出现多次的情况,使用()可以达到分组的功能

这样写Byron{3},只会匹配Byronnn,这样写(Byron){3}才能匹配ByronByronByron

当不希望捕获某些分组,只需要在分组内加上?:,也就是这么(?:Byron)写。

(8)反向引用

当包含分组的正则表达式进行过test,match,search这些方法之后,每个分组都被放在一个特殊的地方以备将来使用,这些存储是分组中的特殊值,我们称之为反向引用 

let text = '2018-07-09'

let reg = /(\d{4})-(\d{2})-(\d{2})/g

/*
    $1是(\d{4})的匹配内容,代表yyyy
    $2是第一个(\d{2})的匹配内容,代表MM
    $3是第二个(\d{2})的匹配匹配内容,代表DD
*/
text=text.replace(reg, '$2/$3/$1')   // 07/09/2018

(9)RegExp对象属性

常用对象属性主要有以下几种:

1.global: 是否全文搜索,默认false

2.ignore case:是否大小写敏感,默认是false

3.multiline:多行搜索,默认值是false

4.lastIndex:是当前表达式匹配内容的最后一个字符的后一位,用于规定下一次匹配的起始位置,lastIndex 属性被 RegExp 对象的 exec 和 test 方法修改.并且它是可写的. 

var re = /[A-Z]/;  
//exec方法执行后,修改了re的lastIndex属性,  
var str = "Hello,World!!!";  
var arr = re.exec(str);  
alert(re.lastIndex);//0,因为没有设置全局标志  
re = /[A-Z]/g;  
arr = re.exec(str);  
alert(re.lastIndex);//1  
arr = re.exec(str);  
alert(re.lastIndex);//7  

注意:当匹配失败(后面没有匹配),或lastIndex值大于字符串长度时,再执行exec等方法会将lastIndex设为0(开始位置) 

5.source:正则表达式的文本字符串

(10)字符串对象方法

1.search方法

String.prototype.search(reg)

search方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,方法返回第一个匹配结果的index,查找不到则返回-1

说明:

search方法不执行全局匹配,它将忽略标志g,并且总是从字符串的开始进行检索,因此,它不会产生类似于test方法的问题;

不输入正则表达式则search方法将会自动将其转为正则表达式

2.match方法

String.prototype.match(reg)

match方法将检索字符串,以找到一个或多个与reg匹配的文本,reg是否具有标志g对结果影响很大。

说明:

非全局调用

如果reg没有标识g,那么match方法就只能在字符串中执行一次匹配,如果没有找到任何匹配的文本,将返回null,否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。

返回数组的第一个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。

除了常规的数组元素之外,返回的数组还含有2个对象属性:

  • index:声明匹配文本的起始字符在字符串的位置
  • input:声明对stringObject的引用
    let reg = /\d(\w)\d/
    
    let text = '$1a2b3c4e5e'
    
    // 子表达式是 /\w/,匹配a
    let result = text.match(reg)      // ["1a2", "a"]
    
    result.index                    // 1
    
    // 不管lastIndex
    result.lastIndex                // 0
    
    result.input                    // '$1a2b3c4e5e'

    全局调用

    如果regexp具有标志g则match方法将执行全局检索,找到字符串中的所有匹配子字符串。如果没有找到任何匹配的子串,否则,返回一个数组。

    数组元素中存放的是字符串中所有的匹配子串,而且也没有index属性或input属性。

    let reg = /\d(\w)\d/g
    
    let text = '$1a2b3c4e5e'
    
    let result = text.match(reg)        // ["1a2", "3c4"]
    
    result.index                       // undefined
    
    result.input                       // undefined
    
    result.lastIndex                   // 0

    3.split方法

    String.prototype.split(reg)

我们经常使用split方法将字符串分割为字符数组:

'a, b, c, d'.split(',')         // ["a", "b", "c", "d"]

在一些复杂的分割情况下我们可以使用正则表达式解决:

'a, b, c, d'.split(/,/)         // ["a", "b", "c", "d"]

'a1b2c3d'.split(/\d/)           // ["a", "b", "c", "d"]

4.

replace方法

replace方法有三种形态:

String.prototype.replace(str, replaceStr)

String.prototype.replace(reg, replaceStr)

'a1b1c1'.replace('1', 2)        // 'a2b1c1'

'a1b1c1'.replace(/1/g, 2)       // 'a2b2c2'

String.prototype.replace(reg, function)

function会在每次匹配替换的时候调用,有四个参数

1.匹配字符串

2.正则表达式分组内容,没有分组则没有该参数

3.匹配项在字符串中的index

4.原字符串

'a1b2c3d4e5'.replace(/\d/g, (match, index, origin) => {
    console.log(index)
    return parseInt(match) + 1
})

// 1 3 5 7 9
// 'a2b3c4d5e6'


'a1b2c3d4e5'.replace(/(\d)(\w)(\d)/g, (match, group1, group2, group3, index, origin) => {
    console.log(match)
    return group1 + group3
})

// '1b2' '3d4'
// ''a12c34e5       => 去除了第二个分组\w匹配到的b和d

(11)正向前瞻(先行断言)和负向前瞻(先行否定断言)

正向前瞻:只有当字符后面跟着某个特定字符才去捕获它 ?=

负向前瞻:只有当字符后面不跟着某个特定字符时才去匹配它  ?!

注意:执行前瞻和负向前瞻之类的运算时,正则表达式引擎会留意字符串后面的部分,然而却不移动index 

//正向前瞻  
re = /([a-z]+(?=\d))/i;  
//我们要匹配后面跟一个数字的单词,然后将单词返回,而不要返回数字  
str = "abc every1 abc";  
alert(re.test(str));//true  
alert(RegExp.$1);//every  
alert(re.lastIndex);//使用前瞻的好处是,前瞻的内容(?=\d)并不会当成一次匹配,下次匹配仍从它开始  
//负向前瞻(?!)  
re = /([a-z](?!\d))/;i  
//将匹配后面不包含数字的字母,并且不会返回(?!\d)中的内容  
str = "abc1 one";  
alert(re.test(str));  
alert(RegExp.$1);//one  

JS正则表达式从入门到入土(1)—— REGEXP对象

JS正则表达式从入门到入土(2)—— 元字符和字符类

JS正则表达式从入门到入土(3)—— 范围类

JS正则表达式从入门到入土(4)—— 预定义类与边界

JS正则表达式从入门到入土(5)—— 量词

JS正则表达式从入门到入土(6)—— 贪婪模式与非贪婪模式

JS正则表达式从入门到入土(7)—— 分组

JS正则表达式从入门到入土(8)—— REGEXP对象属性

JS正则表达式从入门到入土(9)—— test方法以及它的那些坑

JS正则表达式从入门到入土(10)—— 字符串对象方法

猜你喜欢

转载自blog.csdn.net/u012149906/article/details/91814199