Skip to content

模式修饰

作者:Yuan Tang
更新于:5 个月前
字数统计:837 字
阅读时长:3 分钟

正则表达式在执行时会按他们的默认执行方式进行,但有时候默认的处理方式总不能满足我们的需求,所以可以使用模式修正符更改默认方式。

修饰符说明
i不区分大小写字母的匹配
g全局搜索所有匹配内容
m视为多行
s视为单行忽略换行符,使用. 可以匹配所有字符
yregexp.lastIndex 开始匹配
u正确处理四个字符的 UTF-16 编码

i

将所有tydumpling.com 统一为小写

js
let fn = 'tydumpling.com tydumpling.COM'
fn = fn.replace(/tydumpling\.com/gi, 'tydumpling.com')
console.log(fn)

g

使用 g 修饰符可以全局操作内容

js
let fn = 'tydumpling'
fn = fn.replace(/u/, '@')
console.log(fn) // 没有使用 g 修饰符是,只替换了第一个

let fn = 'tydumpling'
fn = fn.replace(/u/g, '@')
console.log(fn) // 使用全局修饰符后替换了全部的 u

m

用于将内容视为多行匹配,主要是对 ^$ 的修饰

将下面是将以 #数字开始的课程解析为对象结构,学习过后面讲到的原子组可以让代码简单些

js
const fn = `
  #1 js,200元 #
  #2 php,300元 #
  #9 tydumpling.com # tydumpling
  #3 node.js,180元 #
`
// [{name:'js',price:'200元'}]
const lessons = fn.match(/^\s*#\d+\s+.+\s+#$/gm).map((v) => {
  v = v.replace(/\s*#\d+\s*/, '').replace(/\s+#/, '');
  [name, price] = v.split(',')
  return { name, price }
})
console.log(JSON.stringify(lessons, null, 2))

u

每个字符都有属性,如L属性表示是字母,P 表示标点符号,需要结合 u 模式才有效。其他属性简写可以访问

网站查看。

js
// 使用\p{L}属性匹配字母
const fn = 'tydumpling2010.不断学习前端,加油!'
console.log(fn.match(/\p{L}+/u))

// 使用\p{P}属性匹配标点
console.log(fn.match(/\p{P}+/gu)) // [., ,, !]

字符也有 unicode 文字系统属性 Script=文字系统,下面是使用 \p{sc=Han} 获取中文字符 han为中文系统,其他语言请查看

js
const fn = `
张三:010-99999999,李四:020-88888888`
const res = fn.match(/\p{sc=Han}+/gu)
console.log(res) // ['张','三','李','四']

使用 u 模式可以正确处理四个字符的 UTF-16 字节编码

js
const str = '𝒳𝒴'
console.table(str.match(/[𝒳𝒴]/)) // 结果为乱字符"�"

console.table(str.match(/[𝒳𝒴]/u)) // 结果正确 "𝒳"

lastIndex

RegExp 对象lastIndex 属性可以返回或者设置正则表达式开始匹配的位置

  • 必须结合 g 修饰符使用
  • exec 方法有效
  • 匹配完成时,lastIndex 会被重置为 0
js
const fn = '前端之路要努力'
let reg = /前端(.{2})/g
reg.lastIndex = 10 // 从索引10开始搜索
console.log(reg.exec(fn))
console.log(reg.lastIndex)

reg = /\p{sc=Han}/gu
while ((res = reg.exec(fn)))
  console.log(res[0])

y

我们来对比使用 yg 模式,使用 g 模式会一直匹配字符串

js
const fn = 'udunren'
const reg = /u/g
console.log(reg.exec(fn))
console.log(reg.lastIndex) // 3
console.log(reg.exec(fn))
console.log(reg.lastIndex) // 3
console.log(reg.exec(fn)) // null
console.log(reg.lastIndex) // 0

但使用y 模式后如果从 lastIndex 开始匹配不成功就不继续匹配了

js
const fn = 'udunren'
const reg = /u/y
console.log(reg.exec(fn))
console.log(reg.lastIndex) // 1
console.log(reg.exec(fn)) // null
console.log(reg.lastIndex) // 0

因为使用 y 模式可以在匹配不到时停止匹配,在匹配下面字符中的 qq 时可以提高匹配效率

js
const fn = '前端之路渐行渐远,退路已经遥遥无期'

const reg = /(\d+),?/y
reg.lastIndex = 7
while ((res = reg.exec(fn))) console.log(res[1])

Contributors

Yuan Tang