正则表达式
在写发表评论的功能时常会看见一个表情的功能,想到应该是需要用正则表达式结合来完成,所以学了一下正则表达式,以便考核顺利完成。
-
正则表达式概述
- 什么是正则表达式
- **正则表达式(Regular Expression)**是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也是对象
- 正则表通常被用来检索、替换那些符合某个模式(规则)的文本,例如验证表单:用户名表单只能输入英文字母、数字或则和下划线,昵称输入框可以输入中文(匹配)。此外,正则表达式还常用于过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等。
- 正则表达式的特点
- 灵活性、逻辑性和功能性非常的强
- 可以迅速地用极简单的方式达到字符串的复杂控制
- 对于刚接触的人来说,比较晦涩难懂。比如:^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$ ,这是验证邮箱的正则表达式
- 实际开发,一般都是直接复制写好的正则表达式,但是要求会使用正则表达式并且根据实际情况修改正则表达式。比如用户名:/^[a-z0-9_-]{3,16}$/
- 什么是正则表达式
-
正则表达式在JavaScript中的使用
-
创建正则表达式
在JavaScript中,可以通过两种方式创建一个正则表达式
-
通过调用RegExp对象的构造函数创建
-
var 变量名 = new RegExp(/表达式/); var regexp = new RegExp(/123/);
-
-
通过字面量创建
-
var 变量名 = /表达式/; var rg = /123/;
-
-
-
测试正则表达式test
-
test()正则对象方法,用于检测字符串是否符合该规则,该对象会返回true或false,其参数是测试字符串
-
regexObj.test(str) -
regexObj是写的正则表达式
-
str是我们要测试的文本
-
就是检测str文本是否符合我们写的正则表达式规范regexObj
-
-
-
正则表达式中的特殊字符
-
正则表达式的组成
- 一个正则表达式可以由简单的字符构成,比如/abc/,也可以是简单和特殊字符的组合,比如/ab*c/。其中特殊字符也被称为元字符,在正则表达式中是最具有特殊意义的专用符号,如:^、$、+等
- 正则表达式里面不需要加引号,不管是数字型还是字符串型
- 特殊字符非常多,可以参考:
- MDN:developer.mozilla.org/zh-CN/docs/…
- jQuery手册:正则表达式部分
- 正则测试工具:tool.oschina.net/regex
-
边界符
-
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符。
-
边界符 说明 ^ 表示匹配行首的文本(以谁开始) $ 表示匹配行尾的文本(以谁结束) -
//边界符 ^ $ var rg = /abc/; // /abc/表示只要包含有abc这个字符串返回的都是true console.log(re.test('abc')); console.log(re.test('abcd')); console.log(re.test('aabcd')); //结果均为true var reg = /^abc/; console.log(re.test('abc')); //结果为true console.log(re.test('abcd')); //结果为true console.log(re.test('aabcd')); //结果为false var reg1 = /^abc$/; //实现精确匹配abc console.log(re.test('abc')); //true console.log(re.test('abcd')); //false console.log(re.test('aabcd')); //false -
如果^和$在一起,表示必须是精确匹配
-
-
字符类
-
[]表示有一系列字符可供选择,只要匹配到其中一个就可以了。所有可供选择的字符都放在方括号内
var rg = /[abc]/; //只要包含有a或包含有b或包含有c都返回为true console.log(rg.test('andy')); //true console.log(rg.test('red')); //false var rg1 = /^[abc]$/ //三选一,只有是a或者是b或者是c这三个字母才返回true console.log(rg1.test('aa')); //false console.log(rg1.test('a')); //true-
[-]方括号内部 范围符-
var rg2 = /^[a-z]$/ //26个英文字母(小写)任何一个字母返回true console.log(rg2.test('a')); //true console.log(rg2.test(1)); //false console.log(rg2.test('A')); //false -
字符组合
//字符组合 var rg3 = /^[a-zA-Z0-9_-]$/; //26个英文字母(大小写)及0到9及下划线及短横线任何一个字母返回true -
[^]方括号内部取反符
-
注意如果[]中含有^的话,其意义为取反,不可与边界符混淆
-
//取反 var rg4 = /^[^a-zA-Z0-9_-]$/; //注意第二个^表示的是取反,即不能出现26个英文字母(大小写)及0到9及下划线及短横线任何一个字母
-
-
-
量词符
-
量词符用来设定某个模式出现的次数
-
量词 说明 * 重复零次或更多次 + 重复一次或更多次 ? 重复零次或一次 {n} 重复n次 {n,} 重复n次或更多次 {n,m} 重复n到m次 -
//*相当于 >=0 var reg = /^a*$/ console.log(reg.test('aaaa')); console.log(reg.test('')); //均为true //+相当于>=1 var reg = /^a+$/ console.log(reg.test('aaaa')); //true console.log(reg.test('')); //false //?相当于0||1 var reg = /^a?$/ console.log(reg.test('aaaa')); //false console.log(reg.test('')); //true console.log(reg.test('a')); //true //{3}就是重复3次 var reg = /^a{3}$/ console.log(reg.test('aaa')); //true console.log(reg.test('aa')); //false //{3,}就是重复大于等于3次 var reg = /^a{3,}$/ console.log(reg.test('aaaa')); //true console.log(reg.test('aa')); //false //{3,16} 表示重复大于等于3次 且 小于等于16次 var reg = /^a{3,16}$/ console.log(reg.test('aaaa')); //true console.log(reg.test('a')); //false
-
-
括号总结
- 大括号——量词符,里面表示重复次数
- 中括号——字符集合。匹配方括号中的任意字符
- 小括号——表示优先级
- 可以在线测试:c.runoob.com/
-
预定义类
-
预定义类指的是某些常见模式的简写方式
-
正则里面的或者:|
-
预定类 说明 \d 匹配0-9之间的任意数字,相当于[0-9] \D 匹配所有0-9以外的字符,相当于[ ^0-9] \w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_] \W 匹配所有字母、数字和下划线意外的字符,相当于[ ^A-Za-z0-9_] \s 匹配空格(包括换行符、制表符、空格符等),相当于[\t\r\n\v\f] \S 匹配非空格的字符,相当于[ ^\t\r\n\v\f] -
座机号码验证
//座机号码验证:全国座机号码两种格式: 010-12345678 或者 0530-1234567 var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/; 或者 var reg = /^\d{3,4}\d{7,8}$/;
-
-
表单验证
-
手机号码: /^1[3|4|5|6|7|8][0-9]{9}$/ QQ: /[1-9][0-9]{4,}/ 昵称(中文) : /^[\u4e00-\u9fa5]{2,8}$/ 密码: /^[a-zA-Z]0-9_-]{6,16}/ //表单验证的函数 function regexp(ele,reg) { ele.onblur = function() { if(reg.test(this.value)) { this.nextElementSibling.className = 'success'; this.nextElementSibling.innerHTML = '恭喜你输入正确' } else [ this.nextElementSibling.className = 'error'; this.nextElementSibling.innerHTML = '输入错误' ] } }
-
-
-
断言
-
先行断言
- “先行断言”指的是,
x只有在y前面才匹配,必须写成/x(?=y)/。 - 比如,只匹配百分号之前的数字,要写成
/\d+(?=%)/。
- “先行断言”指的是,
-
先行否定断言
-
“先行否定断言”指的是,
x只有不在y前面才匹配,必须写成/x(?!y)/ -
比如,只匹配不在百分号之前的数字,要写成
/\d+(?!%)/。 -
/\d+(?=%)/.exec('100% of US presidents have been male') // ["100"] /\d+(?!%)/.exec('that’s all 44 of them') // ["44"]
-
-
后行断言
- “后行断言”正好与“先行断言”相反,
x只有在y后面才匹配,必须写成/(?<=y)x/。 - 比如,只匹配美元符号之后的数字,要写成
/(?<=\$)\d+/。
- “后行断言”正好与“先行断言”相反,
-
后行否定断言
-
“后行否定断言”则与“先行否定断言”相反,
x只有不在y后面才匹配,必须写成/(?<!y)x/。 -
比如,只匹配不在美元符号后面的数字,要写成
/(?<!\$)\d+/。 -
/(?<=\$)\d+/.exec('Benjamin Franklin is on the $100 bill') // ["100"] /(?<!\$)\d+/.exec('it’s is worth about 90$') // ["90"]
-
-
-
正则表达式中的替换
-
replace替换
-
replace()方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或者是一个正则表达式
-
stringObject.replace(regexp/substr,replacement) 例子: var text = document.querySelector('textarea') var btn = document.querySelector('button') var div = document.querySelector('div') btn.onclick = function() { div.innerHTML = text.value.replace(/激情/g,'**'); //将激情替换为** } -
第一个参数:被替换的字符串 或者 正则表达式
-
第二个参数:替换为的字符串
-
返回值是一个替换完毕的新字符串
-
-
正则表达式参数
-
/表达式/[switch] -
switch(也成为修饰符)按照什么样的模式来匹配。
-
g:全局匹配
-
i:忽略大小写
-
gi:全局匹配+忽略大小写
-
u:含义为“Unicode 模式”,用来正确处理大于
\uFFFF的 Unicode 字符。-
也就是说,会正确处理四个字节的 UTF-16 编码
-
可以用unicode来检查是否设置了u模式
const r1 = /hello/; const r2 = /hello/u; r1.unicode // false r2.unicode // true
-
-
y:叫做“粘连”(sticky)修饰符。
-
y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。 -
var s = 'aaa_aa_a'; var r1 = /a+/g; var r2 = /a+/y; r1.exec(s) // ["aaa"] r2.exec(s) // ["aaa"] r1.exec(s) // ["aa"] r2.exec(s) // null -
如上例子,g和y都是从上一次匹配成功的下一个位置开始匹配。
-
第一次匹配的时候都匹配成功'aaa'
-
第二次匹配的时候,g匹配到了aa,因为只需要在下一个位置之后有能够匹配到的就行
-
但是y匹配不到,因为下一个是_,而y需要严格从下一个位置开始匹配,所以匹配不到(这就是粘连)
-
可以用sticky检查是否设置了y
var r = /hello\d/y; r.sticky // true
-
-
s:使得
.可以匹配任意单个字符。-
正则表达式中,点(
.)是一个特殊字符,代表任意的单个字符,但是有两个例外。一个是四个字节的 UTF-16 字符,这个可以用u修饰符解决;另一个是行终止符(line terminator character)。 -
所谓行终止符,就是该字符表示一行的终结。以下四个字符属于“行终止符”。
- U+000A 换行符(
\n) - U+000D 回车符(
\r) - U+2028 行分隔符(line separator)
- U+2029 段分隔符(paragraph separator)
- U+000A 换行符(
-
/foo.bar/.test('foo\nbar') // false /foo.bar/s.test('foo\nbar') // true -
可以用dotAll检查是否设置了s
const re = /foo.bar/s; re.dotAll // true
-
-
flag属性返回正则表达式的修饰符
// ES6 的 flags 属性 // 返回正则表达式的修饰符 /abc/ig.flags // 'gi'
-
-
-