美文网首页
正则相关

正则相关

作者: 行走的蛋白质 | 来源:发表于2020-03-06 22:50 被阅读0次

regular expression


  • 千分位
str.replace(/(\d)(?=(\d{3})+(\.)?)/g, '$2,');

正则表达式的创建

  • 字面量模式 let reg = /\d+/; 缺点是无法拼接变量
  • 构造函数模式 let reg = new RegExp('\d+'); 可以拼接变量,可以有第二个参数值为修饰符
// 全局匹配数字为例,下述两个等同
let reg01 = /\d+/g
reg01 = new RegExp('\\d+', 'g')

元字符和修饰符两部分组成

元字符
  • 量词元字符:设置出现的次数
符号 含义
* 零到多次
+ 一到多次
? 零次或一次
{ n } 出现 n 次
{ n, } 出现 n 到多次也就是至少 n 次
{ n, m } 出现 n 到 m 次
  • 特殊元字符:单个或者组合在一起代表特殊的含义
符号 含义
\ 转义字符
\n 换行符
. 非 \n
^ 以哪一个字符作为开始
$ 以哪一个字符作为结束
\d 0~9之间的一个数字
\D 非 \d
\w 数字、字母、_ 下划线中的任意一个字符
\W 非 \w
\s 一个空白字符 - 空格、制表、换页符等
\t 制表符 - TAB 键 - 四个空格
\b 匹配一个单词的边界
x|y x 或者 y 中的一个字符
[xyz] x 或者 y 或者 z 中的一个字符
[^xy] 除了 x y 中的任意一个字符
[a-z] a 到 z 这个范围中的任意一个字符比如 [a-z0-9A-Z_] === \w
[^a-z] 非 [a-z]
() 正则中的分组符号
(?:) 只匹配不捕获
(?=) 正向预查
(?!) 反向预查
  • 普通元字符:代表的就是本身含义
    /protein/: 此正则匹配的就是 "protein"
修饰符
符号 含义
i ignoreCase 忽略单词大小写匹配
m multiline 可以进行多行匹配
g global 全局匹配

易混淆的中括号 [] () ?

[] 的用法
  • 里面出现的字符一般都代表其本身的含义 \d 是个例外它还代表数字
// 比如 /^[@+]$/ 代表 @ 或者 + 其中一个
// /^[@+]+\$/ 代表 @ 或者 + 其中一个出现一次或者多次(每次都是独立事件)
let reg03 = /^[@+]$/
console.log(reg03.test('@+')) // false

reg03 = /^[@+]+$/
console.log(reg03.test('@+')) // true
  • 中括号中不存在多位数
// 比如 /^[18]$/ 代表 1 或者 8
//  /^[(18)]$/ 代表 ( 或者 ) 或者 1 或者 8
// /^[(12-78)]$/ 代表 ( 或者 ) 或者 2 到 7 之前的数字或者 1 或者 8
let reg04 = /^[18]$/
console.log(reg04.test('1')) // true
console.log(reg04.test('8')) // true
console.log(reg04.test('18')) // false

reg04 =  /^[12-78]$/
console.log(reg04.test('1')) // true
console.log(reg04.test('6')) // true
console.log(reg04.test('8')) // true
console.log(reg04.test('18')) // false
() 的含义
  • 提升优先级
  • 分组捕获
  • 分组引用,就是通过数 "\数字" 让其代表和对应分组出现一模一样的内容
let str2 = 'book' // 'look' 'hook'这种重复的元素
let reg = /^[a-zA-Z]([a-zA-Z])\1[a-zA-Z]$/
console.log(reg.exec(str2))
? 的含义
  • 左边是非量词元字符,代表零次或一次
  • 左边是量词元字符,代表取消贪婪性
  • (?:) 只匹配不捕获
  • (?=) 正向预查
  • (?!) 反向预查

常用正则实例

有些具体还是要根据实际业务变通

1. 验证是否为有效数字
/** 
* 1. 可能出现 +- 也可能不出现 --- [+-] 或者 (+|-)?
* 2. 一位数位 0-9 都可以,多位数首位不为 0 --- (\d|([1-9]\d+))
* 3. 小数位可能有可能没有,如果有小数点后面必须有数字 --- (\.\d+)?
*/
// let reg06 = /^[+-]?(\d|[1-9]+)(\.\d+)?$/  // 忽略了多位数从第二位开始可能会有 0 的情况
let reg06 = /^[+-]?(\d|([1-9]\d+))(\.\d+)?$/
2. 验证密码
/**
* 数字、字母、下划线
* 6 ~ 16 位
*/
let reg07 = /^\w{6,16}$/
3. 验证真实姓名
/**
* 1. 汉字 /^[\u4E00-\u9FA5]$/
* 2. 长度 2 ~ 10 位
* 3. 可能有译名 ·汉字
*/
let reg08 = /^[\u4E00-\u9FA5]{2,10}(·[\u4e00-\u9FA5]{2,10}){0,2}$/;
4. 验证邮箱
/**
* 1. 开头是数字、字母、下划线,一到多位 --- \w+
* 2. 接下来 -数字、字母、下划线或者 .数字、字母、下划线,它们的整体 0 到多位 --- ((-\w+)|(\.\w+))*
* 1. 2. => 邮箱的名字由 数字、字母、下划线开始和结束,中间可以有不连续的 - 或者 . 出现
* 中间 为 @ 符号
* 3. @ 后面紧跟数字、字母,一到多位 --- [a-zA-Z0-9]+
* 4. 最后匹配域名 一个 . 后面跟一到多个数字或者字母 --- \.[a-zA-Z0-9]+
* 5. 在 4 之前匹配 . 或者 - 后面跟一到多个数字或者字母,它们整体出现 0 到多次 --- ((\.|-)[a-zA-Z0-9]+)*
*/
let reg09 = /^\w+((-\w+)|(\.\w+))*@[a-zA-Z0-9]+((\.|-)[a-zA-Z0-9]+)*\.[a-zA-Z0-9]+$/
5. 身份证号码
/**
 * 1. 一共 18 位
 * 2. 最后一位可能是 X
 * => /^\d{17}[0-9X]$/ /^\d{17}(\d|X)$/
 * 3. 规则 - 前六位代表省市县
 * 4. 规则 - 中间八位为出生年月日
 * 5. 规则 - 最后一位是 X 或者数字
 * 6. 规则 - 倒数第二位偶数是女,基数是男
 * 7. 规则 - 其余两位根据上述数字计算得出
 * => 小括号第二个作用:分组捕获,即不仅匹配整体信息还可以单独捕获小分组的内容
 */
let reg10 = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d{1})(\d|X)$/
reg10.exec('130622199708092345') // ["130622199708092345", "130622", "1997", "08", "09", "4", "5", index: 0, input: "130622199708092345", groups: undefined]
// 根据捕获数组可以查询对应省市县,可以知道出生年月日,可以知道性别
// 如果不需要捕获可以用 ?: 只匹配不捕获来处理
let reg10 = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d{1})(?:\d|X)$/
reg10.exec('130622199708092345') // ["130622199708092345", "130622", "1997", "08", "09", "4", index: 0, input: "130622199708092345", groups: undefined]

正则的捕获

实现捕获的方法
  • RegExp.prototype 的方法 exec 和 test
  • String.prototype 的方法 replace\match\splite
exec 方法
  • 结果是 null 或者一个数组
let reg11 = /\d+/
let str1 = 'jfla1989protein1997'
let str2 = 'protein'

console.log(reg11.exec(str1)) // [ '1989', index: 4, input: 'jfla1989protein1997', groups: undefined ]
console.log(reg11.exec(str2)) // null
  • 懒惰性让它匹捕获到第一个符合条件的内容就会停止
    懒惰性的原因:正则有一个 lastIndex 属性,代表下一次匹配的起始位置。exec 之后这个值不会改变,每一次都是从字符串的开始位置 0 查找
  • 用全局修饰符 g 来改变 lastIndex 的值,从而打破懒惰性,如下实例形成一个闭环
let reg12 = /\d+/g
let str1 = 'jfla1989protein1997'

console.log(reg12.lastIndex) // 0
console.log(reg12.exec(str1)) // console.log(reg12.lastIndex)
console.log(reg12.lastIndex) // 8
console.log(reg12.exec(str1)) // [ '1997', index: 15, input: 'jfla1989protein1997', groups: undefined ]
console.log(reg12.lastIndex) // 19
console.log(reg12.exec(str1)) // null
console.log(reg12.lastIndex) // 0
console.log(reg12.exec(str1)) // console.log(reg12.lastIndex)
console.log(reg12.lastIndex) // 8
  • 字符串的 match 方法可以捕获所有
console.log(str1.match(reg12)) // [ '1989', '1997' ]
test 方法

RegExp.$1 ~ RegExp.$9 获取当前匹配的第一到第九个信息

let str4 = '{2020}年{3}月{6}日'
let reg4 = /\{(\d+)\}/g

console.log(reg4.test(str4)) // true
console.log(RegExp.$1) // 2020

console.log(reg4.test(str4)) // true
console.log(RegExp.$1) // 3

console.log(reg4.test(str4)) // true
console.log(RegExp.$1) // 6

console.log(reg4.test(str4)) // false
console.log(RegExp.$1) // 6

console.log(reg4.test(str4)) // true 同样形成一个闭环
console.log(RegExp.$1) // 2020
replace 字符串中实现替换的方法一般伴随正则使用
  • 实例 1 '2020-03-06' === 2020年03月06日
let str13 = '2020-03-06'
let reg13 = /^(\d{4})-(\d{2})-(\d{2})$/
let str131 = str13.replace(reg13, "$1年$2月$3日")
console.log(str131) // 2020年03月06日

实例 1 解析:

  1. replace 首先拿正则和字符串进行匹配,然后第二个参数接受一个回调函数,匹配几次就会执行几次
  2. 回调函数接收实参信息 - 为 exec 捕获到的数组里面的值对应实例 1 如下:
let str132 = str13.replace(reg13, (initialstr, $1, $2, $3) => {
    console.log(initialstr, $1, $2, $3) // 2020-03-06 2020 03 06
})
  1. 回调函数的返回值即为 replace 要替换的正则匹配到的内容
let str133 = str13.replace(reg13, (initialstr, ...args) => {
    let [$1, $2, $3] = args

    $2.length < 2 ? $2 = '0' + $2 : $2
    $3.length < 2 ? $3 = '0' + $3 : $3

    return $1 + '年' + $2 + '月' + $3 + '日'
})
console.log(str133) // 2020年03月06日
  • 实例 2 单词首字母大写
let str14 = 'good good study, day day up!'
let reg14 = /\b([a-zA-Z])([a-zA-Z]*)\b/g

let str141 = str14.replace(reg14, (initialstr, ...args) => {
    // 回调函数执行匹配的次数
    let [$1, $2] = args
    return $1.toUpperCase() + ($2 ? $2 : '')
})
console.log(str141) // Good Good Study, Day Day Up!
正则捕获的贪婪性

默认情况下,捕获的时候是按照当前正则所匹配的最长结果来获取

let str3 = 'jfla1987protein1997'
let reg3 = /\d+/g
console.log(str3.match(reg3)) // [ '1987', '1997' ]

reg3 = /\d/g
console.log(str3.match(reg3)) // [ '1', '9', '8', '7', '1', '9', '9', '7' ]
// 在量词元字符后面加 ? 则取消贪婪模式,按照最短结果来获取
reg3 = /\d+?/g
console.log(str3.match(reg3)) // [ '1', '9', '8', '7', '1', '9', '9', '7' ]

相关文章

  • 正则相关

    正则表达式基本语法 正则表达式常见字符 正则表达式特殊字符 正则表达式数量词 正则表达式边界匹配 正则表达式逻辑或...

  • 正则相关

    ^a 以a开头的字符/s 空白字符/S 非空白字符/d 匹配一个数字字符,/\d/ = /[0-9]/

  • 正则相关

    regular expression 正则表达式的创建 字面量模式 let reg = /\d+/; 缺点是无法...

  • 三剑客_grep

    grep grep 相关参数 grep + 正则表达式(扩展正则)

  • PHP 基础篇 - PHP 正则官方文档汇总

    一、PCRE 正则语法 下面是 PHP 的 PCRE 正则语法(模式语法)相关文档,详情请查阅相关链接: 简介 分...

  • 可视化正则表达式整理

    整理一些常见的正则表达式(附可视化链接) 数字相关 字符串相关 密码相关 时间相关 其他 判断是否匹配正则判定规则...

  • linux shell正则表达式

    正则 普通正则表达式 扩展正则表达式 普通正则表达式 正则表达式 位置相关的正则^: 表示锚定行首,此字符后面的任...

  • 手机号.邮箱.身份证等相关正则表达式

    主要是对NSString的扩展验证相关 ///////////////////////////// 正则表达式相关...

  • iOS-正则表达式使用

    正则表达式与NSPredicate连用 正则表达式类 分组的使用 相关资料 常用正则表达式

  • Android常用的一些正则校验

    整理一部分常用相关正则

网友评论

      本文标题:正则相关

      本文链接:https://www.haomeiwen.com/subject/wtotkhtx.html