JavaScript(E5,6) 正则学习总结学习,可看可不看!
栏目: JavaScript · 发布时间: 6年前
内容简介:正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法。一种是使用字面量,以斜杠表示开始和结束。另一种是使用RegExp构造函数。
正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法。
创建方式有两种方式:
一种是使用字面量,以斜杠表示开始和结束。
var regex = /xyz/ 复制代码
另一种是使用RegExp构造函数。
var regex = new RegExp('xyz'); 复制代码
它们的主要区别是,第一种方法在引擎编译代码时,就会新建正则表达式,第二种方法在运行时新建正则表达式,所以前者的效率较高。而且,前者比较便利和直观,所以实际应用中,基本上都采用字面量定义正则表达式。
2.实例属性
- i:忽略大小写
- m:多行模式
- g:全局搜索
3.实例方法
3.1 RegExp.prototype.test()
正则实例对象的test方法返回一个布尔值,表示当前模式是否能匹配参数字符串。
/小智/.test('小智 终身学习执行者') // true 复制代码
reg.exec(str) 返回匹配结果数组,不匹配则返回null,每执行一次exec就向后匹配一次
3.2 RegExp.prototype.exec()
3.2.1 reg.exec(str) 返回匹配结果数组,不匹配则返回null,每执行一次exec就向后匹配一次
var s = '_x_x'; var r1 = /x/; var r2 = /y/; r1.exec(s) // ["x"] r2.exec(s) // null 复制代码
3.2.1.2如果表达式里有括号(),称为组匹配,返回结果中,第一个是整体匹配结果,后面依次是每个括号匹配的结果
var s = '_x_x'; var r = /_(x)/; r.exec(s) // ["_x", "x"] 复制代码
exec方法的返回数组还包含以下两个属性:
- input:整个原字符串。
- index:整个模式匹配成功的开始位置(从0开始计数)。
var r = /a(b+)a/; var arr = r.exec('_abbba_aba_'); arr // ["abbba", "bbb"] arr.index // 1 arr.input // "_abbba_aba_" 复制代码
3.2.3 如果表达式中有g选项进行全局搜索,则可以多次使用 exec,下次的匹配从上次的结果后开始
var reg = /a/g; var str = 'abc_abc_abc' var r1 = reg.exec(str); r1 // ["a"] r1.index // 0 reg.lastIndex // 1 var r2 = reg.exec(str); r2 // ["a"] r2.index // 4 reg.lastIndex // 5 var r3 = reg.exec(str); r3 // ["a"] r3.index // 8 reg.lastIndex // 9 var r4 = reg.exec(str); r4 // null reg.lastIndex // 0 复制代码
4.字符串的实例方法
4.1 str.match(reg) 与 reg.exec相似,但是,如果使用g选项,则str.match一次性返回所有结果。
var s = 'abba'; var r = /a/g; s.match(r) // ["a", "a"] r.exec(s) // ["a"] 复制代码
4.2 str.search(reg,返回匹配成功的第一个位置,如果没有任何匹配,则返回-1。
'_x_x'.search(/x/) // 1 复制代码
4.3 str.replace(reg,newstr)
用第一个参数reg去匹配,用第二个参数newstr 去替换,正则表达式如果不加g修饰符,就替换第一个匹配成功的值,否则替换所有匹配成功的值。
'aaa'.replace('a', 'b') // "baa" 'aaa'.replace(/a/, 'b') // "baa" 'aaa'.replace(/a/g, 'b') // "bbb" 复制代码
4.4 str.split(reg[,maxLength])
用匹配的模式切割,第二个参数是限制返回结果的最大数量
5. 匹配规则
5.1 字面量字符和元字符
大部分字符在正则表达式中,就是字面的含义,比如/a/匹配a,/b/匹配b。如果在正则表达式之中,某个字符只表示它字面的含义(就像前面的a和b),那么它们就叫做“ 字面量字符 ”(literal characters)。 除了字面量字符以外,还有一部分字符有特殊含义,不代表字面的意思。它们叫做“元字符”(metacharacters),主要有以下几个。
(1) 点字符(.)点字符(.)匹配除回车(\r)、换行(\n)、行分隔符(\u2028)和段分隔符(\u2029)以外的所有字符。
/c.t/ 复制代码
上面代码中,c.t匹配c和t之间包含任意一个字符的情况,只要这三个字符在同一行,比如cat、c2t、c-t等等,但是不匹配 coot 。
(2)位置字符
-
^表示字符串的开始位置
-
$表示字符串的结束位置
// test必须出现在开始位置 /^test/.test('test123') // true
// test必须出现在结束位置 /test$/.test('new test') // true
// 从开始位置到结束位置只有test /^test /.test('test test') // false
(3)选择符(|)
竖线符号(|)在正则表达式中表示“或关系”(OR),即cat|dog表示匹配cat或dog。
/11|22/.test('911') // true 复制代码
上面代码中,正则表达式指定必须匹配11或22。
5.2 转义符
正则表达式中那些有特殊含义的元字符,如果要匹配它们本身,就需要在它们前面要加上反斜杠。比如要匹配+,就要写成+。
/1+1/.test('1+1') // false /1\+1/.test('1+1') // true 复制代码
正则表达式中,需要反斜杠转义的,一共有12个字符:^、.、[、$、(、)、|、*、+、?、{和\。需要特别注意的是,如果使用RegExp方法生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次。
(new RegExp('1\+1')).test('1+1') // false (new RegExp('1\\+1')).test('1+1') // true 复制代码
5.3 字符类
字符类(class)表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内,比如[xyz] 表示x、y、z之中任选一个匹配。
/[abc]/.test('hello world') // false /[abc]/.test('apple') // true 复制代码
有两个字符在字符类中有特殊含义。
(1)脱字符(^)如果方括号内的第一个字符是 [^xyz]
表示除了x、y、z之外都可以匹配:
/[^abc]/.test('hello world') // true /[^abc]/.test('bbc') // false 复制代码
如果方括号内没有其他字符,即只有[^],就表示匹配一切字符,其中包括换行符。相比之下,点号作为元字符(.)是不包括换行符的。
var s = 'Please yes\nmake my day!'; s.match(/yes.*day/) // null s.match(/yes[^]*day/) // [ 'yes\nmake my day'] 复制代码
上面代码中,字符串s含有一个换行符,点号不包括换行符,所以第一个正则表达式匹配失败;第二个正则表达式[^]包含一切字符,所以匹配成功。
(2)连字符(-)
某些情况下,对于连续序列的字符,连字符(-)用来提供简写形式,表示字符的连续范围。比如,[abc]可以写成[a-c],[0123456789]可以写成[0-9],同理[A-Z]表示26个大写字母。
/a-z/.test('b') // false /[a-z]/.test('b') // true 复制代码
以下都是合法的字符类简写形式。
[0-9.,] [0-9a-fA-F] [a-zA-Z0-9-] [1-31] 复制代码
上面代码中最后一个字符类[1-31],不代表1到31,只代表1到3。
另外,不要过分使用连字符,设定一个很大的范围,否则很可能选中意料之外的字符。最典型的例子就是[A-z],表面上它是选中从大写的A到小写的z之间52个字母,但是由于在 ASCII 编码之中,大写字母与小写字母之间还有其他字符,结果就会出现意料之外的结果。
/[A-z]/.test('\\') // true 复制代码
上面代码中,由于反斜杠('')的ASCII码在大写字母与小写字母之间,结果会被选中。
5.4 预定义模式
预定义模式指的是某些常见模式的简写方式。
[0-9] [^0-9] [A-Za-z0-9_] [^A-Za-z0-9_] [ \t\r\n\v\f] [^ \t\r\n\v\f]
// \s 的例子 /\s\w*/.exec('hello world') // [" world"] // \b 的例子 /\bworld/.test('hello world') // true /\bworld/.test('hello-world') // true /\bworld/.test('helloworld') // false // \B 的例子 /\Bworld/.test('hello-world') // false /\Bworld/.test('helloworld') // true 复制代码
通常,正则表达式遇到换行符(\n)就会停止匹配。
var html = "<b>Hello</b>\n<i>world!</i>"; /.*/.exec(html)[0] // "<b>Hello</b>" 复制代码
上面代码中,字符串html包含一个换行符,结果点字符(.)不匹配换行符,导致匹配结果可能不符合原意。这时使用\s字符类,就能包括换行符。
var html = "<b>Hello</b>\n<i>world!</i>"; /[\S\s]*/.exec(html)[0] // "<b>Hello</b>\n<i>world!</i>" 复制代码
上面代码中,[\S\s]指代一切字符。
5.5 重复类
模式的精确匹配次数,使用大括号({})表示。{n}表示恰好重复n次,{n,}表示至少重复n次,{n,m}表示重复不少于n次,不多于m次。
/lo{2}k/.test('look') // true /lo{2,5}k/.test('looook') // true 复制代码
上面代码中,第一个模式指定o连续出现2次,第二个模式指定o连续出现2次到5次之间。
5.6 量词符
-
?
问号表示某个模式出现0次或1次,等同于{0, 1}
。 -
*
星号表示某个模式出现0次或多次,等同于{0,}
。 -
+
加号表示某个模式出现1次或多次,等同于{1,}
。
5.7 贪婪模式
上一小节的三个量词符,默认情况下都是最大可能匹配,即匹配直到下一个字符不满足匹配规则为止。这被称为贪婪模式。
var s = 'aaa'; s.match(/a+/) // ["aaa"] 复制代码
上面代码中,模式是/a+/,表示匹配1个a或多个a,那么到底会匹配几个a呢?因为默认是贪婪模式,会一直匹配到字符a不出现为止,所以匹配结果是3个a。
如果想将贪婪模式改为非贪婪模式,可以在量词符后面加一个问号。
var s = 'aaa'; s.match(/a+?/) // ["a"] 复制代码
除了非贪婪模式的加号,还有非贪婪模式的星号(*)和非贪婪模式的问号(?)
+? *? ??
5.8 组匹配
(1)概述正则表达式的括号表示分组匹配,括号中的模式可以用来匹配分组的内容。
/fred+/.test('fredd') // true /(fred)+/.test('fredfred') // true 复制代码
上面代码中,第一个模式没有括号,结果+只表示重复字母d,第二个模式有括号,结果+就表示匹配fred这个词。
下面是另外一个分组捕获的例子。
var m = 'abcabc'.match(/(.)b(.)/); m // ['abc', 'a', 'c'] 复制代码
上面代码中,正则表达式/(.)b(.)/一共使用两个括号,第一个括号捕获a,第二个括号捕获c。
注意,使用组匹配时,不宜同时使用g修饰符,否则match方法不会捕获分组的内容。
var m = 'abcabc'.match(/(.)b(.)/g); m // ['abc', 'abc'] 复制代码
正则表达式内部,还可以用\n引用括号匹配的内容,n是从1开始的自然数,表示对应顺序的括号。
/(.)b(.)\1b\2/.test("abcabc") // true 复制代码
上面的代码中,\1表示第一个括号匹配的内容(即a),\2表示第二个括号匹配的内容(即c)。
(2)非捕获组
** (?:x)
**称为非捕获组(Non-capturing group),表示不返回该组匹配的内容,即匹配的结果中不计入这个括号。
非捕获组的作用请考虑这样一个场景,假定需要匹配foo或者foofoo,正则表达式就应该写成/(foo){1, 2}/,但是这样会占用一个组匹配。这时,就可以使用非捕获组,将正则表达式改为/(?:foo){1,2}/,它的作用与前一个正则是一样的,但是不会单独输出括号内部的内容。
var m = 'abc'.match(/(?:.)b(.)/); m // ["abc", "c"] 复制代码
上面代码中的模式,一共使用了两个括号。其中第一个括号是非捕获组,所以最后返回的结果中没有第一个括号,只有第二个括号匹配的内容。
(3)先行断言
x(?=y)称为先行断言(Positive look-ahead),x只有在y前面才匹配,y不会被计入返回结果。比如,要匹配后面跟着百分号的数字,可以写成/\d+(?=%)/。
“先行断言”中,括号里的部分是不会返回的。
var m = 'abc'.match(/b(?=c)/); m // ["b"] 复制代码
上面的代码使用了先行断言,b在c前面所以被匹配,但是括号对应的c不会被返回。
(4)先行否定断言
x(?!y)称为先行否定断言(Negativelook-ahead),x只有不在y前面才匹配,y不会被计入返回结果。比如,要匹配后面跟的不是百分号的数字,就要写成/\d+(?!%)/。
/\d+(?!\.)/.exec('3.14') // ["14"] 复制代码
上面代码中,正则表达式指定,只有不在小数点前面的数字才会被匹配,因此返回的结果就是14。
6. 实战
6.1 消除字符串首尾两端的空格
var str = ' #id div.class '; str.replace(/^\s+|\s+$/g, '') // "#id div.class"
6.2 验证手机号码
var reg = /1[24578]\d{9}/; reg.test('154554568997'); //true reg.test('234554568997'); //false 复制代码
6.3 把手机号码替换成 *
var reg = /1[24578]\d{9}/; var str = '姓名:张三 手机:18210999999 性别:男'; str.replace(reg, '***') //"姓名:张三 手机:*** 性别:男" 复制代码
6.4 匹配网页标签
var strHtlm = '小智小智<div>222222@.qq.com</div>小智小智'; var reg = /<(.+)>.+<\/\1>/; strHtlm.match(reg); // ["<div>222222@.qq.com</div>"] 复制代码
6.5 替换敏感字
let str = '中国共产党中国人民解放军中华人民共和国'; let r = str.replace(/中国|军/g, input => { let t = ''; for (let i = 0; i<input.length; i++) { t += '*'; } return t; }) console.log(r); //**共产党**人民解放*中华人民共和国 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 正则表达式创建方式的区别及编写简单的正则方式(js学习总结)
- ECMAScript 6 学习笔记(四):正则的扩展
- 从 0 开始机器学习 - 正则化技术原理与编程!
- Python学习笔记(八)—使用正则获取网页中所需要的信息。
- 少说话多写代码之Python学习064——标准模块(正则表达式)
- 神经网络中的网络优化和正则化(一):学习率衰减和动态梯度方向
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Intersectional Internet
Safiya Umoja Noble、Brendesha M. Tynes / Peter Lang Publishing / 2016
From race, sex, class, and culture, the multidisciplinary field of Internet studies needs theoretical and methodological approaches that allow us to question the organization of social relations that ......一起来看看 《The Intersectional Internet》 这本书的介绍吧!