【javascript】常用正则分组捕获匹配

前言

  • 今天别人问了个正则问题把我问住了,匹配半天没匹配出来,最终到处找资料搞定了,因为js的正则匹配和其他语言有些区别,还有分组方面有些坑,特此记录下

js正则常用捕获符

  • 必须先弄懂这个,基础就不说了,里面还有些坑。
  • 小括号就是分组,分组里面有这样几种:
    (?=) positive lookahead 正向前瞻型捕获
    (?!) negative lookahead 负向前瞻型捕获
    (?<=) positive lookbehind 正向后顾型捕获
    (?<!) negative lookbehind 负向后顾型捕获
    (?:)非捕获分组
  • 只要使用上面的那几种模式,那么js返回给你的是不包括这个括号里的东西,这个有个特别大的好处,因为js使用正则分组有个坑,就是在全局匹配情况下分组,最后使用RegExp.$1只能出来最后一个匹配的分组,不能把所有匹配到的第一个分组拿出来。我百度了半天没发现全局拿所有分组的办法,如果有人知道怎么做可以留言给我。我百度到最好的解决方法除了这个就是利用lastIndex自己写循环匹配。
  • 于是因为js正则有这个捕获问题,所以上面的模式就变得特别常用。特别是在对全局匹配的情况下。

起组名

  • 一般情况下都是不需要起名,用默认的$1,$2。python里面起名用?P<xxx>,js里起名用?<xxx>,js引用分组使用\k<组名>,默认分组使用\数字

常用符号

  • \w 匹配字母或数字或下划线或汉字。与([0-9a-zA-Z_])等价。

  • \s 匹配任意的空白符

  • \d 匹配数字

  • \b 匹配单词的开始或结束

  • 点(.)表示匹配出换行符以外的任意一个字符串

  • 星号(*)表示匹配前面一个字符串0次或多次

常见匹配需求

一、匹配对象前后有固定字符串

  • 我们拉取了后台数据,是个嵌套好多层的json,但是我就想要所有元素的一个字段,并且提取出来,不使用循环,如果用循环太墨迹了,因为有好几层嵌套。比如:
{"departmentId":1,
"departmentName":"zzz",
	"child":[{"departmentId":2,
				"departmentName":"测试部门",
				"child":[{"departmentId":5,
						"departmentName":"试试"}
						]},
			{"departmentId":3,
			"departmentName":"威风威风",
			"child":[{"departmentId":6,"departmentName":"试试44"}]
			},
			{"departmentId":4,"departmentName":"测试部门2"}
	]
}
  • 需求:我们要把所有层级的departmentName拿出来
  • 思路:前面有个固定字符,后面固定是个引号,由于上面说的js分组无法取全局,所以借助捕获符直接提取目标。格式就是(?<=前面的字符串)(中间的内容)(?=后面的字符串)。这个分组就是前面说的前瞻后顾捕获。
let reg = /(?<="departmentName"\:")(.*?)(?=")/g
console.log(str.match(reg))

[ ‘zzzz’, ‘测试部门’, ‘试试’, ‘威风威风’, ‘试试44’, ‘测试部门2’ ]

  • 代码里中间.*?就是懒惰匹配,就是尽可能短的匹配到中间字符,否则用.*结果就会一直匹配到最后一个部门。

二、匹配页面元素

  • 很多时候,会提取页面标签正则判断。页面标签有个特点,就是会有个相同的闭合标签。
  • 比如:
let str =`"<html><h1>www.yehuozhili.cn</h1></html><html><h1>www.yehuozhili.cn</h1></html>"`
  • 我们想按html分成2组
let reg = /\<(\w*)\>.*?\<\/\1\>/g
console.log(str.match(reg))
//输出[
//  '<html><h1>www.yehuozhili.cn</h1></html>',
//  '<html><h1>www.yehuozhili.cn</h1></html>'
//]
  • 其中\w表示任意英文,加个*表示多个,这个\1就表示默认的第一个分组了,就是第一个标签里提取的英文,这样可以保证左边是什么标签右边闭合是什么标签。
  • 如果想匹配h1标签呢?我们把\w*换成h1即可。
let reg2 = /\<(\h1)\>.*?\<\/\1\>/g
console.log(str.match(reg2))
//输出 [ '<h1>www.yehuozhili.cn</h1>', '<h1>www.yehuozhili.cn</h1>' ]
  • 那么我想要标签里内容怎么做?如果是非全局匹配,那比较简单,如果全局匹配,就有点复杂。
  • 我们可以放弃原有的标签分组,直接写死,然后利用分组捕获提取。
let reg2 = /(?<=\<\h1\>).*?(?=\<\/h1\>)/g
console.log(str.match(reg2))
//输出  [ 'www.yehuozhili.cn', 'www.yehuozhili.cn' ]

三、路由匹配

  • 路由匹配有个特点,比如/user ,如果是精准匹配,那么/user/或者/user都是可以通的。但是/user/xxx是不能通的,/usersxxsd也不能通
  • 思路:前面没啥说的,主要是后面,可能有/,如果有/后面不能有东西,如果没/必须精准匹配字。所以使用括号分组但不包括,这个组可能有,可能没有就是问号,最终都是直接结束,所以$。如果有/,那么里面必须结尾没东西,用前瞻捕获来看。
let str =`/user`
let reg = /^\/user(?:\/(?=$))?$/g
console.log(str.match(reg))
  • 这里介绍个生成路由的正则库path-to-regexp,使用它就可以生成路由正则,和上面那个一样。
let pathToRegexp=require('path-to-regexp')
let regexp = pathToRegexp('/user',[],{end:true});
console.log(regexp)
  • 再介绍个正则查看网站。可以很清楚看见正则效果是什么样的。我实验了下,好像不支持js设置分组名。?P的python设置分组名也认不得。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JavaScript正则表达式和Java正则表达式在语法上有一些差异,但是它们的基本概念和用法是相似的。下面是将JavaScript正则表达式转换为Java正则表达式的一些常见规则: 1. 语法差异: - JavaScript正则表达式使用斜杠(/)作为定界符,而Java正则表达式使用双引号(")作为定界符。 - JavaScript正则表达式中的特殊字符需要进行转义,而Java正则表达式中的特殊字符不需要转义。 2. 字符类: - JavaScript正则表达式中的字符类使用方括号([])表示,而Java正则表达式中使用方括号([])或者Unicode转义(\p{...})表示。 - JavaScript正则表达式中的字符类可以使用连字符(-)表示范围,而Java正则表达式中需要使用Unicode转义(\uXXXX)表示范围。 3. 量词: - JavaScript正则表达式中的量词使用花括号({})表示,而Java正则表达式中使用花括号({})或者问号(?)表示。 - JavaScript正则表达式中的贪婪量词默认是贪婪模式,而Java正则表达式中的贪婪量词需要在后面添加问号(?)来表示非贪婪模式。 4. 边界匹配: - JavaScript正则表达式中的边界匹配使用插入符号(^)和美元符号($)表示,而Java正则表达式中使用\A和\Z表示。 5. 其他差异: - JavaScript正则表达式中的捕获组使用圆括号(())表示,而Java正则表达式中使用圆括号(())或者方括号([])表示。 - JavaScript正则表达式中的反向引用使用反斜杠加数字(\1、\2等)表示,而Java正则表达式中使用美元符号加数字($1、$2等)表示。 以上是一些常见的JavaScript正则表达式转换为Java正则表达式的规则。具体转换时,还需要根据具体的正则表达式进行适当的调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

业火之理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值