百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

简单正则一手掌握

xsobi 2025-01-06 16:07 1 浏览


常用字符

正则中很多需要强记的字符,这里列出常用的字符和其表达的含义:


匹配特殊字符本身时需要转义,共有以下几个:

* . ? + $ ^ [ ] ( ) { } | \ /
  • 其中 / 在字面量中需要转义,在构造函数中不需要,如下匹配一个斜杠 /。
const reg = /\//
const reg = new RegExp('/')
  • 在字面量中带一个转义符 \ 的用构造函数写要带两个转义符 \\,如下匹配一个字符串 . 。
const reg = /\./
const reg = new RegExp('\\.')

常用方法

js 中的正则表达式分为字面量和构造函数两种:

// 字面量
const reg = /[0-9a-z]/g
// 构造函数
const reg = new RegExp('[0-9a-z]', 'g')

其中字面量中不能包含变量,构造函数中可以使用变量:

const name = '幻灵尔依'
const reg = new RegExp(`我的名字叫${name}`)

经常会用 reg.test(str) 方法来判断字符串中是否匹配到了正则表达式:

const reg = /[0-9]/
const str = '文本中有没有数字1234等'
if (reg.test(str)) {
  ...
}

也经常用str.replace(reg, '') 方法来替换字符串中的内容:

const reg = /[0-9]/g
const str = '文本中的数字1234全部替换成x'
const newStr = str.replace(reg, 'x')

也会用到 str.match(reg) 方法来获取匹配到的内容(也可以用reg.exec(str)):

const reg = /[0-9]+[.][0-9]+[.][0-9]+/g
const str = '这里有个表名字叫做 11.11.11'
str.match(reg) // ['11.11.11']
  • match 中的正则表达式如果使用g标志,则将返回与完整正则表达式匹配的所有结果,但不会返回捕获组。
  • 如果未使用g标志,则仅返回第一个完整匹配及其相关的捕获组(Array)。 在这种情况下,返回的项目将具有如下所述的其他属性。

老子曰:下面才是精华

贪婪&非贪婪

* 和 + 限定符都是贪婪的,它们会尽可能多的匹配文字。在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配。

  • 贪婪(默认都是贪婪的)
const str = '<h1>正则表达式</h1>'
const reg = /<.*>/
str.match(reg) // ['<h1>正则表达式</h1>']
  • 非贪婪

const str = '<h1>正则表达式</h1>'
const reg = /<.*?>/
str.match(reg) // ['<h1>']

捕获分组和回溯引用

小括号 () 匹配到的子表达式会被缓存为一个个组,方便后面对其引用。假设要获取html中的 h1 标签:

  • 在正则表达式中使用 \n 可以引用第n个捕获组
const str = '<p>正则表达式</p><h1>正则表达式</h1><h2>正则表达式</h2>'
const reg = /<(h1)>.+?<\/\1>/
str.match(reg) // ['<h1>正则表达式</h1>']
  • 在正则表达式外使用 $n 引用第n个捕获组(RegExp.$n)
const str = 'abc'
const reg = /(abc)/
RegExp.$1 // 'abc'
str.replace(reg, '$1$1') // 'abcabc'

非捕获分组和限定查找

因为捕获组 () 会将每个捕获到的结果缓存下来以便引用,所以会造成内存使用增加。如果只是想用分组的原始功能,而不需要缓存,则可以使用非捕获分组 (?:)

const str = 'abc'
const reg = /(?:abc)/
RegExp.$1 // ''

非捕获分组还有 (?=)、(?<=)、(?!)、(?<!) ,他们比 (?:) 多了限定作用,即只匹配而不会被输出。

前向查找

前向查找是用来限制后缀的。

  1. (?=): 即查找符合限定条件 (?=) 的前面的匹配项(输出内容不包括 (?=) 中的匹配项)
const str = 'a.png b.jpg c.gif d.svg'
// 查找所有 边界开头的、 .svg 前面的 小写字母。
const reg = /\b[a-z](?=.svg)/g
str.match(reg) // ['d']
  1. (?!): 即查找 不符合 限定条件 (?!) 的前面的匹配项(输出内容不包括 (?!) 中的匹配项)
const str = 'a.png b.jpg c.gif d.svg'
// 查找所有边界开头的、 非.svg 前面的、 `.[a-z]{3}` 前面的 小写字母。
const reg = /\b[a-z](?!.svg)(?=\.[a-z]{3})/g
str.match(reg) // ['a', 'b', 'c']

后向查找

后向查找是用来限制前缀的。

  1. 查找符合限定条件 (?<=) 的后面的匹配项(输出内容不包括 (?<=) 中的匹配项)
const str = '1. 1111; 2. 2222; 3. 3333; 4. 4444。'
//  查找所有 序号 后面的项。
const reg = /(?<=\b[0-9]+\.\s).+?[;。]/g
str.match(reg) // ["1111;", "2222;", "3333;", "4444。"]
  1. 查找 不符合 限定条件 (?<!) 的后面的匹配项(输出内容不包括 (?<!) 中的匹配项)
const str = 'a.png b.jpg c.gif d.svg'
// 查找前缀不为 a b c 的后面的项
const reg = /\b(?<![abc]\.)[a-z]{3}/g
str.match(reg) // ['svg']

来个能吃的栗子

一般稍微复杂的正则都是多种规则同时使用的,下面来几个例子吧:

前向查找和后向查找齐用:

假设要获取 <img crossorigin src="https://abcdefg.com" data-img-url="https://test.com"> 中的 data-img-url 属性中的链接。可以确定的是链接左边一定是 data-img-url=" ,右边一定是紧贴着 " (非贪婪)。

const str = '<img crossorigin src="https://abcdefg.com" data-img-url="https://test.com">'
const dataImgUrl = 'data-img-url'
const reg = new RegExp(`(?<=${dataImgUrl}=").+?(?=")`, 'g')
str.match(reg) // ['https://test.com']

回溯引用和非贪婪并用

假如我要获取一段html中的文本,但是我又不想要加了 not-show-in-text 标记的标签中的文本,可以这样:

const notShowInText = 'not-show-in-text'
const html = `
  <p>test1</p>
  <p ${notShowInText} style="text-align: center;">
    <b>表 1.4.4 测试表格</b>
  </p>
  <p>test2</p>
`
const reg = new RegExp(`<([a-z][a-z1-6]*?)[^>]+${notShowInText}[\\s\\S]+?</\\1>`, 'g')
const text = html.replace(reg, '').replace(/<[^>]+>/g, '')

其中最关键的是要匹配到 not-show-in-text 所在的整个标签。([a-z][a-z1-6]*?) 匹配了一个非贪婪的标签名,[^>] 保证了 < 到 > 是一个半个完整的标签,</\\1> 匹配一个闭合的标签, [\\s\\S]+? 匹配了标签见可能出现的任意元素且是非贪婪的。

replace第二个参数可以是回调函数

比如,想把 yyyy-mm-dd 格式,替换成 mm/dd/yyyy 怎么做?

var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, "$2/$3/$1");
console.log(result); // "06/12/2017"

其中 replace 第二个参数里用$1、$2、$3指代相应的分组。等价于如下的形式:

var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, function() {
	return RegExp.$2 + "/" + RegExp.$3 + "/" + RegExp.$1;
});
console.log(result); // "06/12/2017"

也等价于:

var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, function(match, year, month, day) {
	return month + "/" + day + "/" + year;
});
console.log(result); // "06/12/2017"


作者:幻灵尔依
链接:https://juejin.cn/post/6907143412227522567
来源:掘金

相关推荐

听说你还不知道Java代码是怎么运行的?

作者:Jay_huaxiao前言作为一名Java程序员,我们需要知道Java代码是怎么运行的。最近复习了深入理解Java虚拟机这本书,做了一下笔记,希望对大家有帮助,如果有不正确的地方,欢迎提出,感激...

如何开始学习JAVA编程?

#记录我的9月生活#...

java后端开发需要学什么?

Java属于后端开发中最常见的语言之一,Java这种语言的体系比较中立,而且具备了构建多线程的能力,在许多大型互联网平台Java的应用范围特别广泛。  java后端主要涉及到如下4个技术:  第一、S...

细思极恐:你真的会写Java吗?

导语自2013年毕业后,今年已经是我工作的第4个年头了,总在做java相关的工作,终于有时间坐下来,写一篇关于java写法的一篇文章,来探讨一下如果你真的是一个java程序员,那你真的会写java吗?...

七年Java开发的一路辛酸史:分享面试京东、阿里、美团后的心得

前言我觉得有一个能够找一份大厂的offer的想法,这是很正常的,这并不是我们的饭后谈资而是每个技术人的追求。像阿里、腾讯、美团、字节跳动、京东等等的技术氛围与技术规范度还是要明显优于一些创业型公司...

我把Java基础编程及思维导图整理的超级详细,小白都能看懂

Java基础编程及其思维导图目录:Java学习导图一、Java基本语法1.关键字与标识符2.变量分类3.运算符4.流程控制二、数组1.数组概述2.一维数组3.二维数组4.数组常见算法5....

Java 开发中的 9 个实用技巧:案例详解

Java开发中,总有一些技巧能够帮助我们提高代码质量和开发效率。下面,我们来分享9个Java技巧,每个技巧都附上实际案例,帮助你在工作中立刻应用。1.合理使用final关键字...

Java 20年,以后将往哪儿走?

在今年的Java20周年的庆祝大会中,JavaOne2015的中心议题是“Java的20年”。甲骨文公司Java平台软件开发部的副总裁GeorgesSaab的主题演讲就将关注点放在了java...

推荐1个java快速开发项目,让你接私活不用愁

??大家好,我是小编南风吹,每天推荐一个小工具/源码,装满你的收藏夹,让你轻松节省开发效率,实现不加班不熬夜不掉头发!...

教你用Java开发一个简单的JVM

一、前言几年前,接到一个开发任务:用Java开发能运行Java智能合约的虚拟机。在开发Java智能合约时,只能使用智能合约SDK提供的类和一些Java常用类(8种基本数据类型包装类;String、Bi...

java实战教程(一)软件开发流程&amp;开发模式

这里小编为了方便处于不同学习阶段的童鞋,准备了三个系列的文章,java系列教程、java实战教程、java进阶教程,对于刚入坑的童鞋,可以先按照这三个系列教程一步步的了解,循序渐进,java实战系列教...

Java 核心技术之入门指南:全面解析Java概述

大家好,这里是Java码牛!Java核心技术入门:全面解析Java概述一、引言Java,作为一门在当今信息技术领域中被广泛应用于企业级开发的主流编程语言,其核心技术的精准掌握对于众多开发者而言,具有...

小白如何轻松上手Java开发?

Java,这款流行的编程语言,被广大开发者所钟爱。但对于初学者来说,如何入门确实是一个大问题。尤其对于毫无经验的小白,从何处开始、如何推进,都是关键。本文将带你走进Java的世界,为你揭示从零到一的进...

初学Java应该知道的知识点:Java的程序开发是什么?

Java的程序开发是什么呢?下面和千锋广州小编一起来看看吧!一般来说,Java的程序开发包括三个步骤:编写程序,编译程序,运行程序编写程序——Java源代码,.Java文件编译程序——Javac用来进...

厉害了!全靠经典之作-Java编程思想,把小白教的明明白白

今天我们来聊聊这本《Java编程思想》从我学习Java的经验来看,《ThinkinginJava》是讲解Java编程的最佳书籍!  这本书不仅详细地介绍Java语法、知识点、API类库使用,更...