关于JS的正则表达式骚操作

本文是lhyt本人原创,希望用通俗易懂的方法来理解一些细节和难点。转载时请注明出处。文章最早出现于本人github

0.前言

本文主要介绍了捕获和非捕获的概念,并举了一些例子,这些都是正则表达式在js中进阶的一些用法。后面有彩蛋哦

1.捕获

1.1RegExp对象的相关属性

一般用()括住的就是捕获组,而且类似于算术中的括号,从左到右,逐层去括号。比如存在(A)((B)C)这种,他捕获到的将会是(A)((B)C)、(B)、((B)C),并在内存中存放,可以通过RegExp对象的$属性来访问到。

/(1((2)3))/.test('123')

RegExp.$1 //123

RegExp.$2 //2

RegExp.$3 //23

/(((1)2)3)/.test('123')

RegExp.$1 //123

RegExp.$2 //12

RegExp.$3 //1

这个顺序,按左括号的顺序来算的,第几个(就表示第几个$符号属性,一般从1开始,最多$9

还有一些旧的RegExp长属性名,在高级程序设计108页里面

简写的话还是有很多不兼容的问题的,最好写全称

1.2数字的反向引用

有的人就问,用正则怎么匹配AABB类型的词语?比如高高兴兴、亮晶晶这些。在正则里面反斜杠+数字就可以做到,表示重复第n个捕获组的内容,这个n和上面$后面的数字同理:

/(.)\1(.)\2/.test('高高兴兴') //TRUE,第一个和第二个相同,第三四个相同

/(.)(.)\2/.test('亮晶晶') // TRUE ,后面两个相同

2.非捕获

以 (?) 开头的组是非捕获组,它不捕获文本 ,也不针对组合计进行各种操作,不将匹配到的字符存储到内存中,从而节省内存。也就是上面所讲的$属性他都不会具有。一般用于只需要检测结果的情况。

(?:a)非捕获一个a

/(?:a)1(?:b)/.test('a1b') //true

RegExp.$1 //''

var reg = /(?:\d{4})-(\d{2})-(\d{2})/

var date = '2018-01-02'

reg.test(date)

RegExp.$1 // 01

RegExp.$2 // 02

2.1断言

也有人叫前瞻,顾名思义,就是往前面(右边)看,看看是不是某个东西。

(?=x) 匹配后面是x的数据 :

/i am (?=a)/.test('i am a') //你右边是a

(?!x) 匹配后面不是x的数据

/i am (?!a)/.test('i am b') //你右边不是a

2.2筛选

(?!B)[A-Z]:在大写字母集合中,除去B

/(?!B)[A-Z]/.test('A') //true

/(?!B)[A-Z]/.test('B') //false

3.匹配模式

3.1惰性匹配和贪婪模式

*? 重复0次或更多次

+? 重复一次或更多次

?? 重复0次或一次

{n,}? 重复n次或更多次

{n,m}? 重复n到m次

以上所有的匹配都是尽可能的少重复,只要满足条件就行了,不继续匹配了,在某个程度来说也是性能优化的方法之一。

那么贪婪模式就是没有做了上面的措施的都属于贪婪模式,比如正则元字符、量词单独出现的情况。

对于字符串'abbba'使用/ab*/g和/ab*? /g

贪婪模式:ab* 结果:abbb 和 a,第一次找到了a,继续找发现后面接几个b也是符合的,直到发现了第二个a才停止,再找到第二个a

惰性匹配:ab*? 结果:a 和 a,第一次找到了a,*的要求是不需要b也可以,所以停止,接着又找到第二个a

彩蛋:

检测一个数是否是质数的方法

相信大家都见过一个很强大的函数,一行代码判断出一个数是不是质数:

function isPrime(n){

return n<2?false:!/^(11+?)\1+$/.test(Array(n+1).join('1'))

}

看上去好像很牛逼,容我细细道来:

首先最小的质数是2,所以先判断是否小于2

如果大于2,先创建一个长度是n的字符串,里面铺满了1。Array(n+1)创建n+1个空位(undefined),再用1作为分隔符分开转化为字符串,所以就得到一个长度为n的字符串,全是1组成

^11+?怎么理解

表示以1开头,后面惰性匹配多个1(1个或者无穷个)

\1+$怎么理解

表示重复^11+?这段匹配到的内容

合起来怎么理解

神奇的地方来了,首先,惰性匹配的是一个1,也就是11,后面重复11的整数次,也就是重复2次4次6次...等等,如果刚刚好匹配到了,说明这个数能被整除,说明他不是质数。如果后面的字符串不能构成2的整数倍个11,那么第一轮惰性匹配失败。

接着第二轮惰性匹配,匹配11,也就是前面捕获的是111,那么后面就开始重复111的整数倍,如果刚刚好能匹配完,说明不是质数

接着第三轮,匹配111,捕获到1111,后面重复1111的整数倍

...

直到不能再匹配,说明这个数就是质数。

其实,里面相当于循环

for(var i = 2;i<n;i++){

if(n%i==0){return false}

}

return true

正则的强大,真的是法力无边。jQuery作者正则玩得飞起,号称世界上最强的选择器sizzle,就是强大正则做出来的


原文来自lhyt的github

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容