javaScript——正则表达式

193 阅读7分钟

正则表达式

1. 认识正则

正则表达式(规则表达式)

我们自己来书写规则, 然后专门用来检测 字符串 是否符合规则

创建正则

    1. var reg = /正则在这里边/
    1. var reg = new RegExp('正则写在这里边')
var reg = /abc/ 
console.log(reg)

var reg2 = new RegExp('abcd')
console.log(reg2)

2. 正则的常用方法

1. 匹配

test 匹配字符串是否符合正则规则

true 符合规则 false 不符合

var reg = /abc/     // 匹配一段字符串中是否包含 'abc'

var str1 = 'a'
var str2 = 'ab'
var str3 = 'abc'
var str4 = 'abcd'
var str5 = 'a1b2c3'

console.log(reg.test(str1)) // false
console.log(reg.test(str2)) // false
console.log(reg.test(str3)) // true
console.log(reg.test(str4)) // true
console.log(reg.test(str5)) // false

2. 捕获

语法: 正则.exec(字符串)

  1. 字符串没有符合正则规则的内容
  • 捕获的结果为 null
  1. 正则没有小括号, 没有标识符 g
  • 捕获到的是一个数组, 下标0 是我们捕获到的值
  • 但是不管捕获多少次, 都是从 下标[0]开始, 第一个满足条件的
  1. 有小括号
  • 下标0 是符合正则规则的字符串
  • 从 下标1 开始, 时每个小括号单独捕获出来的内容
  1. 有标识符 g
  • g 叫做全局标识符
  • 第二次捕获的时候, 会从第一次捕获结束的位置开始进行捕获
  • 直到找不到内容, 会返回一个 null
  • 然后再下一次捕获的时候, 会从字符串开始位置重新捕获
// 1. 字符串没有符合正则规则的内容
var reg = /\d{3}/
console.log(reg.exec('qwertyuiop'))

// 2. 正则没有小括号, 没有标识符 g
var reg = /\d{3}/
console.log(reg.exec('qwe123rty456uiop789'))
console.log(reg.exec('qwe123rty456uiop789'))

// 3. 有小括号
var reg = /(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/
var num = '411381200401311234'
console.log(reg.exec(num))

// 4. 有标识符 g
var reg = /\d{3}/g
var str = 'qwe123rty456uiop789'
console.log(reg.exec(str))  // [0]: 123
console.log(reg.exec(str))  // [0]: 456
console.log(reg.exec(str))  // [0]: 789
console.log(reg.exec(str))  // null
console.log(reg.exec(str))  // [0]: 123

3. 正则的元字符

正则表达式的符号, 由两种符号组成

1. 元字符

  • 正则的规则符号
  • 普通文本--正则的规定符号

2. 修饰符

  • 修饰整个正则表达式的符号

普通元字符

    1. \d 表示 一位 数字(0-9)
    1. \D 表示 一位 非数字(除了0-9)
    1. \s 表示 一位 空白内容(空格, 缩进)
    1. \S 表示 一位 非空白内容
    1. \w 表示 一位 数字(0-9)字母(a-zA-Z)下划线(_)
    1. \W 表示 一位 非数字字母下划线的内容
    1. . 表示 一位 非换行内容
    1. \ 表示 转义符
// 1. \d
var reg = /\d/  // 匹配字符串中 包含一位 数字
console.log(reg.test('abcd'))   // false
console.log(reg.test('abcd#$%^&*('))   // false
console.log(reg.test('123456789'))   // true
// 2. \D
var reg = /\D/  // 匹配字符串中 包含一位 非数字
console.log(reg.test('abcd'))   // true
console.log(reg.test('abcd#$%^&*('))   // true
console.log(reg.test('123456789'))   // false
// 3. \s
var reg = /\s/  // 匹配字符串中 包含一位 空白内容
console.log(reg.test('123456!@#$%qwerty'))  // false
console.log(reg.test('123456! @#$%qwerty'))  //true
// 4. \S
var reg = /\S/  // 匹配字符串中 包含一位 非空白内容
console.log(reg.test('123456!@#$%qwerty'))  // true
console.log(reg.test('123456! @#$%qwerty'))  // true
console.log(reg.test(' '))  // false
// 5. \w
var reg = /\w/  // 匹配字符串中 包含一位 数字(0-9)字母(a-zA-Z)下划线(_)
console.log(reg.test('abc'))    // true
console.log(reg.test('a1b2c3'))    // true
console.log(reg.test('a1b2_c3'))    // true
console.log(reg.test('!@#$%^&'))    // false
// 6. \W
var reg = /\W/  // 匹配字符串中 包含一位 非数字字母下划线
console.log(reg.test('abc'))    // false
console.log(reg.test('abc123'))    // false
console.log(reg.test('abc123_'))    // false
console.log(reg.test('!@#$%'))    // true
console.log(reg.test(' '))    // true
// 7. .
var reg = /./    // 匹配字符串中 包含一位 非换行的任意内容
console.log(reg.test('@#$%^'))  // true
console.log(reg.test('asdf'))   // true
console.log(reg.test('123'))    // true
console.log(reg.test('\n'))    // \n    在 JS 中代表换行
 // 8. \
var reg = /\d\.\d/    // . 表示非换行的任意内容,    \.   表示一个小数点, 没有任何特殊含义
/**
 *  var reg = /4.5/
 *  var reg = /\d.5/
 *  var reg = /\d\.5/
 *  var reg = /\d\.\d/
*/
console.log(reg.test('abc'))    // false
console.log(reg.test('5.7'))    // true
console.log(reg.test('100'))    // false

4. 正则的边界元字符

1. ^ 表示开头

2. $ 表示结尾

当 开头与结尾 共同使用时, 表示 字符串 必须是 规则里的内容

var reg = /^\d/  // 表示 字符串开头需要是一位数字
console.log(reg.test('100abc')) // true
console.log(reg.test('abc999')) // false

// var reg = /\d$/ // 表示 字符串结尾需要是一位数字
console.log(reg.test('100abc')) // false
console.log(reg.test('abc999')) // true

var reg = /abc/ // 表示字符串中 包含 'abc'
console.log(reg.test('abcd'))   // true

var reg1 = /^abc$/  // 表示 字符串 必须是 'abc'
console.log(reg1.test('abcd'))  // false

5. 正则的限定元字符

限定了 前一个符号 出现多少次

      • 表示 0~正无穷次
      • 表示 1~正无穷次
    1. ? 表示 0~1 次
    1. {n} 表示 限定 n 次
    1. {n,} 表示 限定 最少 n 次
    1. {n,m} 表示 限定 最少 n 次, 最多 m 次
// 1. *
var reg = /^\d*$/
console.log(reg.test('abc'))    // false
console.log(reg.test('_99'))    // false
console.log(reg.test('66634567890'))    // true
// 2. +
var reg = /^\d+$/
console.log(reg.test('abc'))    // false
console.log(reg.test('_99'))    // false
console.log(reg.test('66634567890'))    // true
console.log(reg.test(' '))    // false
console.log(reg.test('!'))    // false
// 3. ?
var reg = /^\d?$/
console.log(reg.test('6'))  // true
console.log(reg.test('99')) // false
// 4. {n}
var reg = /^\d{3}$/
console.log(reg.test('6'))  // false
console.log(reg.test('99')) // false
console.log(reg.test('777')) // true
console.log(reg.test('4444')) // false
// 5. {n,}
var reg = /^\d{3,}$/
console.log(reg.test('6'))  // false
console.log(reg.test('99')) // false
console.log(reg.test('777')) // true
console.log(reg.test('4444')) // true
// 6. {n,m}
var reg = /^\d{3,4}$/
console.log(reg.test('6'))  // false
console.log(reg.test('99')) // false
console.log(reg.test('777')) // true
console.log(reg.test('4444')) // true
console.log(reg.test('12345')) // false

6. 特殊元字符

  1. ()
  • 含义1: 单独捕获(欠着)
  • 含义2: 一个整体
  1. |
  • 含义: 或 a|b
  1. [] 包含 中括号内 其中一个即可

在中括号中可以书写任意数量的符号,但是字符串只要满足其中一个即可

  1. [^] 非 不包含

在中括号内可以书写任意数量的符号,只要字符串不是其中某一个类型就行

  1. - 到 至 通常和 [] [^] 连用

/[0-9]/ 正则代表的含义 数字 0-9 ,等价于 \d

/[^0-9]/ 正则代表的含义 非数字 0-9 ,等价于 \D

/[^a-z]/ 表示字母 a-z

/[0-9a-zA-Z]/ 等价于 \w

var reg = /^(abc){2}$/
console.log(reg.test('abc'))    // false
console.log(reg.test('abcabc'))    // true
console.log(reg.test('abcqwe'))    // false

var reg = /a|b/
console.log(reg.test('a'))  // true
console.log(reg.test('b'))  // true
console.log(reg.test('c'))  // false
var reg = /^[abcd]$/
//字符串中,包含a b c d 任意一个即可
console.log(reg.test('a')) //true
console.log(reg.test('b')) //true
console.log(reg.test('c')) //true
console.log(reg.test('d')) //true
console.log(reg.test('abcd')) //false

var reg = /^[^abcd]$/
console.log(reg.test('a')) //false
console.log(reg.test('c')) //false
console.log(reg.test('w')) //true

7. 元字符或的分界线在哪里(面试题)

或的分界线为 小括号 或者 正则的边界

// var reg = /^abc|def$/
/**
*  分析:
*      /^abc|def$/
* 
*          ^abc        或者        def$
*/
console.log(reg.test('abc12345678'))    // true
console.log(reg.test('12345678def'))    // true
console.log(reg.test('1234abcdef5678'))    // false
var reg = /^ab(c|d)ef$/
/**
*  分析
*      ^ab     c     ef$
*      ^ab     d     ef$
*/

console.log(reg.test('abcef'))    // true
console.log(reg.test('abdef'))    // true
console.log(reg.test('qwef'))     // false
console.log(reg.test('abqwe'))    // false

8. 正则的重复元字符

符号: \数字

  • \1 \2 \3
  • 含义: 表示 重复 第 n 个小括号的内容, 并且 要求和小括号的内容完全一致
var reg = /^(abc|def)\1$/
/**
*  \1 重复前边第一个小括号的内容, 小括号内如果是 'abc' 那么 \1 的值也需要是 'abc'
*/
console.log(reg.test('abcabc')) // true
console.log(reg.test('defdef')) // true
console.log(reg.test('abcdef')) // false
console.log(reg.test('defabc')) // false
/**
*  要求 字符串是 span 标签 或者 p标签
*/

var reg = /<(span|p)><\/\1>/
/**
*  流程:
*      1. var reg = /<span></span>/
*          !!! 因为 span 的结束标签前有一个 /  JS会把它识别为正则的结束, 所以需要加一个转义符
*      
*      2. var reg = /<span><\/span>/
*          !!! 因为 span 或者 p 标签都可以, 所以 需要将 span 标签开头添加一个 元字符或
*      
*      3. var reg = /<(span|p)><\/span>/
*          !!! 因为 结束标签的文本一定和开始标签相同, 所以可以在结束标签后 写一个 \1  表示重复第一个小括号的内容
* 
*      4. var reg = /<(span|p)><\/\1>/
*/
console.log(reg.test('<span></span>'))
console.log(reg.test('<p></p>'))
console.log(reg.test('<div></div>'))

9. 正则的标识符

书写在正则外面, 用来描述整个正则表达式

  1. i
  • 表示忽略大小写
  1. g
  • 表示 全局
  • 欠着
var reg = /^[abcd]$/i
console.log(reg.test('a')) //true
console.log(reg.test('A')) //true
console.log(reg.test('w')) //false

10. 正则的两大特性 (面试常问)

  1. 懒惰
  • 每次捕获 都是在 下标[0] 的位置开始捕获
  • 解决: 在正则后添加全局标识符 g
  1. 贪婪
  • 每次捕获内容的时候, 尽可能的多去捕获内容
  • 解决: 使用非贪婪限定符 (在原有的限定符后添加一个?) 贪婪限定符

? {n,} {n,m}

非贪婪限定符 *? {n,}?

var str = '<div class="box" id="id_box"><span></span></div>'

// 贪婪捕获
var reg1 = /<div.*>/
console.log(reg1.exec(str)[0])

// 非贪婪捕获
var reg2 = /<div.*?>/
console.log(reg2.exec(str)[0])

11. 案例练习

案例需求:

将 字符串内 所有满足正则规则的 片段 全部捕获出来, 放到一个数组内

var reg = /\d{3}/g
var str = 'qwe123asd456zxc789'
var arr = []

var newStr = reg.exec(str)  // 数组
while (newStr !== null) {
    arr.push(newStr[0])

    newStr = reg.exec(str)
}
console.log(arr)

/**
 *  分析:
 *      首次执行 newStr 是一个数组, 下标0 为 '123'
 * 
 *          满足 while 循环 执行循环内容
 *              1. arr.push(newStr[0])
 *              2. newStr = reg.exec(str)   此时 newStr 是一个数组, 下标0 为 '456'
 * 
 *      第二次执行 newStr 还是一个数组, 下标0 为 '456'
 *          满足 while 循环 执行循环内容
 *              1. arr.push(newStr[0])
 *              2. newStr = reg.exec(str)   此时 newStr 是一个数组, 下标0 为 '789'
 * 
 *      第三次执行 newStr  还是一个数组, 下标0 为 '789'
 *          满足 while 循环 执行循环内容
 *              1. arr.push(newStr[0])
 *              2. newStr = reg.exec(str)   此时 已经没有符合正则规则的内容 所以捕获的值为 null
 * 
 *      第四此执行 newStr 是一个 null
*/

/**
 *  ['123', '456', '789']
*/

12. 正则创建方式的区别

书写标识符

  • 字面量的方式, 直接在正则后书写标识符
  • 内置构造函数的方式, 需要写在第二个参数中
//1.书写标识符
let reg3 = /abc/i
let reg4 = new RegExp('qwe', 'ig')

//2.书写元字符
let reg1 = /\d\w\s.\./
console.log(reg1)

let reg2 = new RegExp('\\d\\w')
console.log(reg2)
/**
*  在字符串中, 如果 书写了 \   那么相当于转义符, 将后边的字符转换为 有意义的字符
* 
*      但是 转换完成之后, \ 就会自动消失,      那么正则拿到的就是一个 具有特殊含义的 字符 d
* 
*      但是又因为 正则中 元字符 必须是 \ + d       结合在一起才是一个元字符, 如果只有一个 d 那么就是一个普通的字母, 没有任何特殊含义
* 
* 
*      解决方式:
*          在原本的 \  前再添加一个 \
*      
*          第一个 \ 将 第二个 \ 转换为没有任何意义的 普通文本, 最终正则拿到的就是一个  没有特殊含义的 \ + d
*          然后按照正则的规则中, \+d 就是一个元字符, 代表的是数字0-9
*/