前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手把手教你认识前端的正则表达式

手把手教你认识前端的正则表达式

作者头像
前端老鸟
发布2022-03-07 14:43:11
4390
发布2022-03-07 14:43:11
举报
文章被收录于专栏:front-end technology

正则表达式

参考:

  1. https://www.jb51.net/tools/zhengze.html
  2. https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/regular-expression-language-quick-reference

Js 中正则表达式的定义

  1. 构造函数方式
代码语言:javascript
复制
var reg = new RegExp('a','gi')
var str = '012a'
console.log(str.search(reg))
  • 第一个参数是正则的内容,第二个参数是修饰符;
  • 修饰符通常有三种,i,g,m;
  • i (IgnoreCase)表示的含义是忽略大小写进行匹配;
  • g ()表示全局匹配即匹配到第一个之后不停止继续匹配;
  • m (Multiline)表示多行匹配即遇到换行后不停止匹配继续直到被匹配字符串结束。
  1. 字面量方式
代码语言:javascript
复制
var reg = /a/gi

Js 中能使用正则表达式的方法有哪些?

String

  1. replace

该方法用来将字符串中的某些子串替换为需要的内容,接受两个参数,第一个参数可以为正则或者子字符串,表示匹配需要被替换的内容,第二个参数为被替换的新的子字符串。如果声明为全局匹配则会替换所有结果,否则只替换第一个匹配到的结果。

代码语言:javascript
复制
'abcabc'.replace(/a/,'A')
'abcabc'.replace(/a/g,'A')
'abcabc'.replace(/a/gi,'S')
  1. search

用来查找第一次匹配的子字符串的位置,如果找到就返回一个 number 类型的 index 值,否则返回-1,它返回的只是第一次匹配的位置。

代码语言:javascript
复制
console.log('hello world!'.search(/l/g))
  1. split

该方法主要用来将一个字符串拆分成一个数组,它接受一个正则或者子字符(串)作为参数,返回一个数组

代码语言:javascript
复制
let str = 'a|b|c'
console.log(str.split('|'))
let str2 = 'a|b c\*\*d'
let arr = str2.split(/\||\s+|\*\*/)
console.log(arr)
  1. match

该方法接受一个正则作为参数,用来匹配一个字符串,它的输出结果在不是全局匹配的情况下和 exec 方法的结果一致即一个数组并带有额外的属性,如果采用全局匹配,则不返回任何和其被匹配字符串相关的信息,只返回匹配的结果。

代码语言:javascript
复制
var str = "hello javascript!"
var reg1 = /a/
console.log(str.match(reg1))
var reg2 = /a/g
console.log(str.match(reg2))

// 小括号问题
var str2 = 'abcabc'
var reg3 = /(b)c/
console.log(str2.match(reg3))
var reg4 = /(b)c/g
console.log(str2.match(reg4))

RegExp

  1. test

该方法用来测试某个字符串是否与正则匹配,匹配就返回 true,否则返回 false。

代码语言:javascript
复制
var reg = /abc/
var str = 'abc'
console.log(reg.test(str))
  1. exec

该方法属于一个比较复杂的方法,它接受一个字符串,返回的是一个数组,数组中第 0 个元素是匹配的子字符串,第二个元素是正则中的第一个子分组匹配的结果(如果有子分组,即正则中存在用圆括号括起来的分组),第三个是正则中第二个子分组匹配的结果(如果有第二个子分组)...以此类推,如果没有正则子分组,那么该数组长度仅仅为 1,就是匹配到的那个子字符串。同时,返回的这个数组同时还是一个对象,它拥有两个属性,分别为 index 表示当前匹配到的子字符串所处的位置,input 属性表示被匹配的原始字符串。最后,该方法中的正则对象如果不是全局匹配,即没有 g 修饰符,则每次调用只会从字符串开头处匹配第一个结果,且每次调用结果都是一样的。只有指定为全局匹配,才能够按照从左往右依次去匹配,每次调用匹配一个结果,正则对象的 lastIndex 属性前进到本次匹配的末尾位置,下回再调用的时候,会从 lastIndex 处开始匹配而不是从头匹配

代码语言:javascript
复制
var reg = /abc/g
var str = 'abcdefgabcefg'
var arr = reg.exec(str)

while(arr){
  console.log(arr)
  arr = reg.exec(str)
}
  1. compile

该方法的作用是能够对正则表达式进行编译,被编译过的正则在使用的时候效率会更高,适合于对一个正则多次调用的情况下,如果对一个正则只使用一两次,那么该方法没有特别显著的效应。

接受的参数也是一个正则。

代码语言:javascript
复制
var reg=/[abc]/gi;
console.log(reg.test('a'));
reg=/[cde]/gi;
console.log(reg.test('a'));
reg.compile(reg);
console.log(reg.test('a'));

被编译的正则和没有编译的正则在测试结果上没有任何区别,只是多次调用的效率上会更高一些。

正则工具

RegexBuddy 使用手册

  • mac 环境

正则入门

正则表达式由一些普通字符和一些元字符(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义

元字符

常用元字符

元字符

描述

.

匹配除换行符(“\n”和"\r")以外的任意字符

\w

匹配字母或数字或下划线或汉字

\s

匹配任意的空白符

\d

匹配数字

\b

匹配单词的开始或结束

^

匹配字符串的开始

$

匹配字符串的结束

\

将下一个字符标记符、或一个向后引用、或一个八进制转义符。例如,“\\n”匹配\n。“\n”匹配换行符。序列“\\”匹配“\”而“\(”则匹配“(”。即相当于多种编程语言中都有的“转义字符”的概念。

限定元字符

元字符

描述

*

匹配任意次

+

匹配至少一次或更多次

匹配零次或一次

{n}

匹配 n 次

{n,}

匹配 n 次或更多次

{n,m}

匹配 n 次到 m 次

字符集

元字符

描述

a-z

字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符

1-9

数字范围,匹配指定范围内的任意数字。例如,"1-9"可以匹配 1 到 9 范围内的任意数字

x

匹配 x

分支分组元字符

元字符

描述

()

将( 和 ) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存 9 个),它们可以用 \1 到\9 的符号来引用

|

将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him | her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。

反义

元字符

描述

\W

匹配任意不是字母,数字,下划线,汉字的字符

\S

匹配任意不是空白符的字符

\D

匹配任意非数字的字符

\B

匹配不是单词开头或结束的位置

[^x]

配除了 x 以外的任意字符

[^aeiou]

匹配除了 aeiou 这几个字母以外的任意字符

后向引用

元字符

描述

(exp)

匹配 exp,并捕获文本到自动命名的组里

(?<name>exp)

匹配 exp,并捕获文本到名称为 name 的组里,也可以写成(?'name'exp)

(?:exp)

匹配 exp,不捕获匹配的文本,也不给此分组分配组号

零宽断言

元字符

描述

(?=exp)

匹配 exp 前面的位置

(?<=exp)

匹配 exp 后面的位置

(?!exp)

匹配后面跟的不是 exp 的位置

(?<!exp)

匹配前面不是 exp 的位置

负向零宽断言
注释

(?#comment)

贪婪与懒惰

元字符

描述

*?

重复任意次,但尽可能少重复

+?

重复 1 次或更多次,但尽可能少重复

??

重复 0 次或 1 次,但尽可能少重复

{n,m}?

重复 n 到 m 次,但尽可能少重复

{n,}?

重复 n 次以上,但尽可能少重复

平衡组/递归匹配

有时我们需要匹配像( 100 * ( 50 + 15 ) )这样的可嵌套的层次性结构,这时简单地使用(.+)则只会匹配到最左边的左括号和最右边的右括号之间的内容(这里我们讨论的是贪婪模式,懒惰模式也有下面的问题)。假如原来的字符串里的左括号和右括号出现的次数不相等,比如( 5 / ( 3 + 2 ) ) ),那我们的匹配结果里两者的个数也不会相等。有没有办法在这样的字符串里匹配到最长的,配对的括号之间的内容呢?

为了避免(和(把你的大脑彻底搞糊涂,我们还是用尖括号代替圆括号吧。现在我们的问题变成了如何把 xx <aa aa> yy 这样的字符串里,最长的配对的尖括号内的内容捕获出来?

这里需要用到以下的语法构造:

  • (?'group') 把捕获的内容命名为 group,并压入堆栈(Stack)
  • (?'-group') 从堆栈上弹出最后压入堆栈的名为 group 的捕获内容,如果堆栈本来为空,则本分组的匹配失败
  • (?(group)yes|no) 如果堆栈上存在以名为 group 的捕获内容的话,继续匹配 yes 部分的表达式,否则继续匹配 no 部分
  • (?!) 零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败
其它元字符
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/11/01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正则表达式
    • Js 中正则表达式的定义
      • Js 中能使用正则表达式的方法有哪些?
        • String
        • RegExp
      • 正则工具
        • 正则入门
          • 元字符
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档