正则表达式
- 正则表达式
- 创建一个正则表达式
- 修饰符
- 常用的特殊字符
- 使用正则表达式的方法
- replace
- 指定字符串作为替换项
- 使用场景:
- 交换字符串中的两个单词
- 将"-"链接的方式改为驼峰式(忽略开头的-)
- 将华氏温度转换为响应的摄氏温度
- 常用正则示例
- 判断输入是否是正确的邮箱格式
- 给定字符串 str,检查其是否符合美元书写格式(小数部分若有,则小数长度为2)
- 匹配纯数字或纯小写字母或纯大写字母,且长度在5-16之间(不能输入特殊字符)
- 允许数字、大小写字母、但至少包含其中两种,且长度在8-16之间(不能是纯数字、纯小写字母、纯大写字母,不能输入特殊字符)
- 密码中同时包含数字、大小写字母,且长度在6-20之间(不能输入特殊字符)
- 密码中同时含字母(大或小)和数字且长度在6-20之间(不能输入特殊字符)
- 匹配11位,以137、139、188、186开头的手机号
参考链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_expressions
正则表达式是用于匹配字符串中字符组合的模式 这些模式被用于 RegExp 的 exec 和 test 方法,以及 String 的 match、matchAll、replace、search 和 split 方法
正则表达式
正则表达式是用于匹配字符串中字符组合的模式
创建一个正则表达式
- 字面量方式:
/正则表达式/修饰符(可选)
const reg = /ab+c/i;
console.log(reg.test('abb')) // false
console.log(reg.test('abc')) // true
console.log(reg.test('abbc')) // true
- 调用RegExp对象的构造函数
const reg = new RegExp("ab+c");
修饰符
修饰符 | 含义 |
---|---|
i | 执行对大小写不敏感的匹配。 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止) |
m | 执行多行匹配。 |
const str = 'dog cat and dog'
console.log(str.replace(/dog/, '')) // cat and dog
console.log(str.replace(/Dog/i, '')) // cat and dog
console.log(str.replace(/Dog/ig, '')) // cat and
常用的特殊字符
字符 | 含义 |
---|---|
\ | 1. 在非特殊字符之前的反斜杠表示下一个字符是特殊字符,不能按照字面理解。例:前面没有 “” 的 “b” 通常匹配小写字母 “b”,但如果前面加了 “”,它将不再匹配任何字符,而是表示一个字符边界。 2. 在特殊字符之前的反斜杠表示下一个字符不是特殊字符,应该按照字面理解。 如果你想将字符串传递给 RegExp 构造函数,不要忘记在字符串字面量中反斜杠是转义字符: /[a-z]\s/i 和 new RegExp("[a-z]\\s", "i") 创建了相同的正则表达式 |
^ | 匹配输入的开始。 例:/^A/ 并不会匹配 “an A” 中的 ‘A’,但是会匹配 “An E” 中的 'A |
$ | 匹配输入的结束。 例:/t$/ 并不会匹配 “eater” 中的 ‘t’,但是会匹配 “eat” 中的 ‘t’ |
* | 匹配前一个表达式 0 次或多次。等价于 {0,} 例如,/bo*/ 会匹配 “A ghost boooooed” 中的 ‘booooo’ 和 “A bird warbled” 中的 ‘b’,但是在 “A goat grunted” 中不会匹配任何内容 |
+ | 匹配前面一个表达式 1 次或者多次。等价于 {1,} 例如,/a+/ 会匹配 “candy” 中的 ‘a’ 和 “caaaaaaandy” 中所有的 ‘a’,但是在 “cndy” 中不会匹配任何内容 |
? | 匹配前面一个表达式 0 次或者 1 次。等价于 {0,1} |
. | (小数点)默认匹配除换行符之外的任何单个字符 例如,/.n/ 将会匹配 “nay, an apple is on the tree” 中的 ‘an’ 和 ‘on’,但是不会匹配 ‘nay’。 |
(x) | 它会匹配 ‘x’ 并且记住匹配项。其中括号被称为捕获括号 例:模式 /(foo) (bar) \1 \2/ 中的 ‘(foo)’ 和 ‘(bar)’ 匹配并记住字符串 “foo bar foo bar” 中前两个单词。模式中的 \1 和 \2 表示第一个和第二个被捕获括号匹配的子字符串,即 foo 和 bar,匹配了原字符串中的后两个单词。 而在正则表达式的替换环节,则要使用像 $1、 2 、 . . . 、 2、...、 2、...、n 这样的语法,例如,‘bar foo’.replace(/(…) (…)/, '$2 1 ′ ) 。 1')。 1′)。& 表示整个用于匹配的原字符串 |
(?:x) | 匹配 ‘x’ 但是不记住匹配项。这种括号叫作非捕获括号 |
x(?=y) | 匹配’x’仅仅当’x’后面跟着’y’.这种叫做先行断言。 |
(?<=y)x | 匹配’x’仅当’x’前面是’y’.这种叫做后行断言 |
x(?!y) | 仅仅当’x’后面不跟着’y’时匹配’x’,这被称为正向否定查找 |
(?<!y)x | 仅仅当’x’前面不是’y’时匹配’x’,这被称为反向否定查找。 |
{n} | n 是一个正整数,匹配了前面一个字符刚好出现了 n 次 |
{n,} | n 是一个正整数,匹配前一个字符至少出现了 n 次。 |
{n,m} | n 和 m 都是整数。匹配前面的字符至少 n 次,最多 m 次。如果 n 或者 m 的值是 0,这个值被忽略。 |
[xyz] | 一个字符集合。匹配方括号中的任意字符,包括转义序列。你可以使用破折号(-)来指定一个字符范围。对于点(.)和星号(*)这样的特殊符号在一个字符集中没有特殊的意义。 例:[abcd] 和 [a-d] 是一样的。他们都匹配"brisket"中的‘b’,也都匹配“city”中的‘c’ |
[^xyz] | 一个反向字符集。也就是说, 它匹配任何没有包含在方括号中的字符 |
[\b] | 匹配一个退格 (U+0008)(与\b不一样) |
\b | 匹配一个词的边界。 例:/\bm/匹配“moon”中的‘m’;/oo\b/并不匹配"moon"中的’oo’,因为’oo’被一个“字”字符’n’紧跟着。 /oon\b/匹配"moon"中的’oon’,因为’oon’是这个字符串的结束部分。这样他没有被一个“字”字符紧跟着 |
\B | 匹配一个非单词边界 |
\d | 匹配一个数字。等价于 [0-9] |
\D | 匹配一个非数字字符。等价于 [^0-9] |
\s | 匹配一个空白字符,包括空格、制表符、换页符和换行符。 |
\S | 匹配一个非空白字符 |
\w | 匹配一个单字字符(字母、数字或者下划线)。等价于 [A-Za-z0-9_] |
\W | 匹配一个非单字字符。等价于 [^A-Za-z0-9_] |
\n | 在正则表达式中,它返回最后的第 n 个子捕获匹配的子字符串 (捕获的数目以左括号计数)。 |
使用正则表达式的方法
replace
String.prototype.replace(pattern, replacement)方法返回一个新字符串,其中一个、多个或所有匹配的 pattern 被替换为 replacement。pattern 可以是字符串或 RegExp,replacement 可以是字符串或一个在每次匹配时调用的函数。如果 pattern 是字符串,则只会替换第一个匹配项。原始的字符串不会改变
const str = "Ruth's dog is your dog"
console.log(str.replace("Ruth's", 'my')) // my dog is your dog
console.log(str.replace(/Dog/i, 'cat')) // Ruth's cat is your dog
指定字符串作为替换项
模式 | 插入值 |
---|---|
$$ | 插入一个 “$” |
$& | 插入匹配的子字符串 |
$` | 插入匹配子字符串之前的字符串片段 |
$’ | 插入匹配子字符串之后的字符串片段 |
$n | 插入第 n(索引从 1 开始)个捕获组,其中 n 是小于 100 的正整数。 |
$ | 插入名称为 Name 的命名捕获组 |
replace() 替换多次的唯一情况是传入带有 g 标志的正则表达式
如果 pattern 是一个空字符串,则替换项将被插入到字符串的开头
"xxx".replace("", "_"); // "_xxx"
若replacement为函数,该函数具有以下签名
function replacer(match, p1, p2, /* …, */ pN, offset, string, groups) {return replacement;
}
// 参数如下所示
match: 匹配的子字符串(对应$&)
p1, p2, …pN: 如果 replace() 的第一个参数是 RegExp 对象,则为捕获组(包括命名捕获组)找到的第 n 个字符串。(对应于上面的 $1、$2 等。)例如,如果 pattern 是 /(\a+)(\b+)/,则 p1 是 \a+ 的匹配项,p2 是 \b+ 的匹配项。如果该组是分支的一部分(例如 "abc".replace(/(a)|(b)/, Replacer)),则不匹配的替代项将为 undefined
offset: 原始字符串中匹配子字符串的偏移量。例如,如果整个字符串是 'abcd',而匹配的子字符串是 'bc',那么这个参数将是 1
string: 正在检查的原始字符串
groups: 一个捕获组命名组成的对象,值是匹配的部分(如果没有匹配,则为 undefined)。仅在 pattern 包含至少一个命名捕获组时才存在
参数的确切数量取决于第一个参数是否为 RegExp 对象,以及它有多少个捕获组
function replacer(match, $1, $2, $3, offset, string, groups) {console.log(match) // abc12345#$*%console.log($1) // abc, $2为12345,$3为#$*%console.log(offset) // 0 (偏移量)console.log(string) // abc12345#$*%console.log(groups) // undefined
}
const newString = "abc12345#$*%".replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
使用场景:
交换字符串中的两个单词
const re = /(\w+)\s(\w+)/;
const str = "Maria Cruz";
const newstr = str.replace(re, "$2, $1"); // Cruz, Maria
将"-"链接的方式改为驼峰式(忽略开头的-)
const str = '-webkit-border-image'
const strName = str.replace(/^-/, "").replace(/-([a-z])/g, (_, $1) => $1.toUpperCase()) // webkitBorderImage
将华氏温度转换为响应的摄氏温度
function f2c(x) {function convert(str, p1, offset, s) {return `${((p1 - 32) * 5) / 9}C`;}const s = String(x);const test = /(-?\d+(?:\.\d*)?)F\b/g;return s.replace(test, convert);
}
console.log(f2c('0F')) // -17.77777777777778C
常用正则示例
判断输入是否是正确的邮箱格式
let regemail = /^[\w\._-]+@[\w]+[\.\w]+$/
给定字符串 str,检查其是否符合美元书写格式(小数部分若有,则小数长度为2)
let reg = /^\$\d{1,3}(,\d{3})*(\.\d{2})?$/
匹配纯数字或纯小写字母或纯大写字母,且长度在5-16之间(不能输入特殊字符)
let reg11 = /^(\d+|[a-z]+|[A-Z]+)$/
// console.log(reg11.test('ZZZZ')) // false:111aa,ZZZZ1 ;true:aaaaa,111,ZZZZ
允许数字、大小写字母、但至少包含其中两种,且长度在8-16之间(不能是纯数字、纯小写字母、纯大写字母,不能输入特殊字符)
let reg10 = /^(?![\d]+$)(?![a-z]+$)(?![A-Z]+$)[\da-zA-z]{8,16}$/
// console.log(reg10.test('ZZZZZZz')) // false:123123123,ZZZZZZZ,ZZZZZZ!!!,ZZZZZZz ;true:12312aaaaa,ZZZZZ12312aaaaa
密码中同时包含数字、大小写字母,且长度在6-20之间(不能输入特殊字符)
let reg9 = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[\da-zA-Z]{6,20}$/
// console.log(reg9.test('Z23qwe')) // false:123qwe,123qwe!!!,ZZZ123qwe!!! true:123qweZZZ, Z23qwe
密码中同时含字母(大或小)和数字且长度在6-20之间(不能输入特殊字符)
let reg8 = /^(?=.*\d)(?=.*[a-zA-Z])[\da-zA-Z]{8,16}$/
// console.log(reg8.test('Z12345ZZ!!')) // false:'abcdefgh','agh1','Z12345ZZ!!' true:abcdefgh1,Zgh12345,Z12345ZZ
匹配11位,以137、139、188、186开头的手机号
let reg5 = /^(^137|139|188|186)[0-9]{8}$/
// console.log(reg5.exec('18664570316'))