JS正则表达式、方法及应用

328 阅读1分钟

正则大法好~过一遍正则的知识,有问题的地方望指正。

正则特殊字符

字符 含义 等价于
\ 转译,特殊字符转译为字面字符
^ 匹配开头
$ 匹配结尾
* 0或多次 {0, }
+ 1或多次 {1, }
? 0或1次 {0, 1}
. 换行符之外任何单个字符
(x) 匹配括号中的'x'并记住匹配项(捕获括号)
(?:x) 非捕获组,不返回该匹配内容
例如: 'abc'.match(/(?:.)b(.)/); m // ["abc", "c"] "a"未返回
x|y 匹配x或y
{n} 出现n次
{n, } 至少n次
{n, m} 至少n次,至多m次
[xyz] 匹配括号中的任意字符,[abcd]等同于[a-d]
[^xyz] 反向字符集,匹配任何没有包含在方括号中的字符
\b 匹配一个词的边界。 例如:/\bm/ 匹配“moon”中的“m”
\B 匹配一个词的非边界,词的内部。例如: /\Bn\B/ 匹配 “omoono”中的“中间两个o返回['o', 'o']
\d 匹配一个数字 [0-9]
\D 匹配一个非数字 [^0-9]
\f 匹配一个换页符(U+000C)
\n 匹配一个换行符(U+000A)
\r 匹配一个回车符(U+000D)
[\b] 匹配一个退格符(U+0008)
\t 匹配一个水平制表符(U+0009)
\v 匹配一个垂直制表符(U+000B)
\s 匹配一个空白字符(包括空格、制表符、换页符、换行符) [\t\n\x0B\f\r]
\S 匹配非空白字符 [^\t\n\x0B\f\r]
\w 匹配一个单字字符(字母、数字、下划线) [a-zA-z_0-9]
\W 匹配一个非单字字符 [^a-zA-z_0-9]
\n 返回最后的第n个子捕获匹配的子字符串
例如:/apple(,)\sorange\1/匹配“"apple, orange, cherry, peach."中的'apple, orange,'”
\1代表(,)匹配到的,
\0 匹配NULL(U+0000)字符

零宽断言

方法 描述
(?=exp) 匹配后面跟exp的部分
(?!exp) 匹配后面不跟exp的部分
(?<=exp) 匹配前面是exp的部分
(?<!exp) 匹配前面不是exp的部分

非捕获组

不返回该组匹配内容

let reg = /(?:http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/
reg.exec('http://google.com/')
// ["http://google.com/", "google.com", "/"]
// 非捕获组 http未返回

非贪婪模式

量词,+后面添加?为非贪婪模式,一旦条件满足则不再往下匹配*

符号 描述
*? 0次或多次,匹配时采用非贪婪模式
+? 1次或多次,匹配时采用非贪婪模式
let s = 'aaa';
s.match(/a+/) // ["aaa"]

s.match(/a+?/) // ["a"]

正则的方法

RegExp的方法

方法 描述
exec 返回匹配的数组,未匹配返回null。例如:/\d/.exec('1234')返回[1]
如果正则包含括号则数组第二个成员为第一个括号匹配的部分以此类推
test 测试是否匹配,返回true或false。 例如:/\d/.test('d') 返回false

String的方法

方法 描述
match 字符串中匹配返回数组未匹配返回null。例如:'1234aaaddd22d42'.match(/\d+/g)返回["1234", "22", "42"]
如果正则包含括号则数组第二个成员为第一个括号匹配的部分以此类推,但如果使用修饰符g则返回所有匹配的不包含括号组
matchAll 返回一个迭代器
search 返回匹配到的位置索引,失败返回-1。例如:'aaaaa'.search(/\d+/)返回-1
replace 匹配后使用替换字符串替换掉匹配子字符串。例如:'1aaaaa'.replace(/\d+/, 'a') // "aaaaaa"
第二是参数指代所替换的内容,见下方替换↓
split 使用正则分隔字符串

替代

字符 描述
$& 匹配的子字符串。例如: '1234'.replace(/\d/, '$&替代') // "1替代234"
$` 匹配结果前面的文本。 例如: '1234a'.replace(/[a-z]/, '$替代') // "12341234替代"
$' 匹配结果后面的文本。例如:'1234a'.replace(/4/, "$'替代") // "123a替代a"
$n 匹配成功的第n组内容。例如:'1234a'.replace(/(1)/, "替代$1") // "替代1234a"
? 指代美元符(直接$不就好了吗?)

括号子字符串匹配

let reg = /(\w+)\s(\w+)/
let str = 'John Smith'
let newStr = str.replace(reg, "$2, $1") // S1对应(\w+)匹配到的内容,$2对应(\w+)匹配到的内容
console.log(newStr) // "Smith, John"

正则表达式可选参数flags

标志 描述
g 全局匹配(默认情况下,第一次匹配成功后,正则对象就停止匹配)
i 不区分大小写匹配
m 多行匹配(加上m修饰符以后^和$还好匹配行首和行尾即会识别换行符\n)
s 允许.匹配换行符
u 使用unicode码的模式进行匹配
y 执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始。

正则表达式的声明

let reg = /pattern/flags
// 或者
let reg = new RegExp('pattern', 'flags')

例子

  • 去除首位空格 匹配开头或结尾的空格

    let reg = /^\s+|\s+$/g
    "  dfg ds  ".replace(reg, "") // dfg ds
    
  • 数组去重 先将数组排序后转字符串将相同的多个字符替换成单个字符 但是其实使用new Set是最方便的

    ["a", "b", "c", "a", "b", "c", "b", "c", "c", "d"]
    .sort()
    .join()
    .replace(/(\w)(,\1)+/g, '$1')
    .split(',')
    // ["a", "b", "c", "d"]
    
  • 校验大于0的两位小数 实际业务中很常见

    let reg = /^((0|[1-9]\d*)\.)(0[1-9]|[1-9]0|[1-9]{1,2})$|^[1-9]\d*$/
    // 前部分是0开头或1-9开头的一位或多位整数
    // 后部分为小数点后跟0X|X0|XX两位数组合(X代表1-9任意数字)
    reg.test('0.0') // false
    reg.test('0.00') // false
    reg.test('0.01') // ture
    reg.test('0.123') // false
    reg.test('01.12') // false
    reg.test('12.12') // true
    

参考