正则表达式学习笔记

正则表达式的语法不再多说

正则RegExp类型有几个常用方法:

exec()

该方法是专门为捕获组而设计的。

例:

var text='I love cat and dog and panda';

var pattern=/I love cat( and dog( and panda)?)?/gi;

var matches=pattern.exec(text);

console.log(matches.input)//I love cat and dog and panda

console.log(matches.index)//0

console.log(matches)//[ 'I love cat and dog and panda',

' and dog and panda',

' and panda',

index: 0,

input: 'I love cat and dog and panda' ]

从例子中应该可以隐约体会到捕获组的意思。

我在学习正则表达式的时候,遇到的难点之一就是捕获组和非捕获组。

捕获组就是满足子表达式(就是被括号包含的表达式)的内容。它们是有编号的,方便以后引用。(无论是在正则表达式内外都可以引用)

注意,编号为0的捕获组,指的是符合正则表达式整体的内容。

引用方法是 "/" 加上一个数字。"/1" 引用第1对括号内匹配到的字符串。

那编号是怎么编呢?不然怎么知道引用哪个呢?编号根据左括号的顺序而定。

举个🌰

var text2='meowmeowmeowmeow'

var ptn=/(meow)\1/

var m=ptn.exec(text2);

console.log(m)//[ 'meowmeow', 'meow', index: 0, input: 'meowmeowmeowmeow' ]

看到了吧,\1表示第一个子表达式匹配的内容,所以输出的结果是两个meow。

还有另外一个🌰

var text='I love cat and dog and panda';

var pattern=/I love cat( and dog( and panda)?)?/gi;

var result=text.replace(pattern,'I love kitties and puppies$2')

console.log(result)//I love kitties and puppies and panda

但是有时候数字很不直观,大家知道正则表达式解读起来有时候麻烦,如果复杂过头,写的人自己都不知道写的什么鬼,那怎么办?可不可以自己命名啊?可以(任性

捕获组分为普通捕获组和命名捕获组。

普通捕获组就是刚才介绍的,只用数字编号;而命名捕获组,除了数字编号以外,可以自定义一个捕获组的名字。不过js貌似还不支持命名捕获组(溜了溜了



还有一个鬼登西叫做非捕获组,顾名思义就是我看到你了,但是我不会抓住你,找到你以后就放生你,所以非捕获组是不能引用的。

以下是常用的一些非捕获组

?:pattern 匹配pattern但不获取结果

?=pattern正向预查 比方说p1(?=p2),满足该表达式的内容为后面紧跟着p2的p1

?!pattern反向预查 后面不跟着p2的p1

而类似?<=的后瞻表达式,js也不支持,嘻嘻(再次溜

🌰🌰🌰🌰🌰🌰时间

尝试一下正向预查🌰:

var text2='Windows 95 and Windows 98 and Windows xp'

var ptn=/Windows(?= [\d]+\b)/g;

console.log(text2.replace(ptn,'meow'));//meow 95 and meow 98 and Windows xp

在看看反向预查🌰:

var text2='Windows 95 and Windows 98 and Windows xp'

var ptn=/Windows(?! [\d]+\b)/g;

console.log(text2.replace(ptn,'meow'));//Windows 95 and Windows 98 and meow xp

test()

如果文本有内容匹配正则表达式,返回true,否则返回false

构造函数的属性

摘抄了一下别人的博客,毕竟照着书手打很麻烦

input (简写为$_) 最近一次要匹配的字符串。

lastMatch(简写$&) 最近一次的匹配项

lastParen(简写$+) 最近一次匹配的捕获组。

leftContext(简写$`) input字符串中lastMatch之前的文本

rightContext(简写$') input字符串中lastMatch之后的文本

multiline(简写$*) 布尔值,表示是否所有表达式都使用多行模式。

在进行exec或者test操作以后,可从RegExp对象中提取上述信息

🌰🌰🌰🌰🌰🌰

var text='I love cat and dog and panda';

var pattern=/I love cat( and dog( and panda)?)?/gi;

var matches=pattern.test(text);

console.log(RegExp.input)//I love cat and dog and panda

console.log(RegExp.$_)//I love cat and dog and panda

console.log(RegExp["$_"])//I love cat and dog and panda

match()

返回符合正则表达式的内容(数组),未匹配返回null

🌰

var text2='Windows 95 and Windows 98 and Windows xp'

var ptn=/Windows(?: [\d]+\b)/g;

console.log(text2.match(ptn))//[ 'Windows 95', 'Windows 98' ]

search()

返回匹配到的位置索引,或者在失败时返回-1。

🌰

var text3='abcedefe';

var ptn3=/e/g;

var res=text3.search(ptn3);

console.log(res)//3

var res2=text3.search('/h/g');

console.log(res2)//-1

replace()

刚才讲解的捕获组中,🌰使用了replace方法。

text.replace(reg,替换的内容)

split()

var text3='abcedefe';

var ptn3=/e/;

var res=text3.split(ptn3);

console.log(res)//[ 'abc', 'd', 'f', '' ]

有一点特别魔幻,当时没有仔细看MDN,以为自己忽略了子表达式有什么其它的作用。


其实MDN写得一清二楚……

如果separator包含捕获括号(capturing parentheses),则其匹配结果将会包含在返回的数组中。

varmyString="Hello 1 word. Sentence number 2.";

varsplits=myString.split(/(\d)/);

console.log(splits)//[ 'Hello ', '1', ' word. Sentence number ', '2', '.' ]

当时自己写了一遍,想了想不对呀,split平时不是这个意思呀……

正则加不加括号不都一个意思吗……

下楼拿了个外卖,思考了10分钟,然后再看一遍MDN,呵呵。

嗯就死记硬背得了。反正这个函数任性么。

贪婪模式和懒惰模式

超级难点

添加修饰匹配次数的量词,默认为贪婪模式,尽可能多地匹配,如* + ?

而懒惰模式,是在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配。

贪婪模式的原理:某个字符串str,使用贪婪模式的正则,首先它会从整个字符串开始观察是否符合正则,若不符合,从字符串结尾逐个减去字符,再次检测,以此类推,直到找到符合规则的字符串为止。

而懒惰模式则相反,它从字符串开头逐个添加再检索。

划考点:过滤html标签

思路:

标签是成对的,所以可以在后向引用获取;√

判断标签用〈、 〉符号判定,使用贪婪模式,可以解决其它嵌套标签;√

如果标签相同,比如

1.<div><div></div></div>,如果希望获取整个div,使用贪婪模式

2.<div></div><div></div>,如果希望获取前一个div,使用懒惰模式

要适当使用贪婪模式或者懒惰模式

最后用一道题检测下学习成果:

使用正则表达式实现数字添加千分位

例10000000000会变成10,000,000,000

大神解答专栏在此

大神在专栏里面已经讲的非常清楚。

文章首先阐明了位置的定义。

正则表达式里面,\b表示一个边界,表示\w与\W、^、$之间的位置。

之前一直认为边界符只是一个用来匹配位置的标记,并没有太大的作用,从来没有想过边界替换,所以好像也对这道题无从下手。

明确了位置的定义后,我们可以想象,千分位的添加,实质上就是每三个数字前面的位置添加一个逗号,而不必使用循环和各种判定条件。(我曾想过用split实现来着...)

那么要怎么表示\w之间的边界呢?需要对\b进行非操作吗?

在前面我介绍过正向预查,事实上正向预查可以表示特定的边界,因为可以看作它判定了预查对象前面的表达式+预查对象前面的位置。

现在刚学正则表达式,还不太熟练,我们一步步,一个个元字符和子表达式添加上去,练习自己对正则表达式的解读。

var s ="3102546864";

首先照着概念,我们希望取每3个数字的前面的边界

var re1=/(?=\d{3})/g;//结果: ,3,1,0,2,5,4,6,864 

从开头判定,开头后面的确跟着3个数字310,于是开头的位置放置一个逗号;再右移,数字3的后面跟着3个数字102,于是3和102之间放置一个逗号……以此类推,直到864是最后一组3个数字。

var re2=/(?=(\d{3})+)/g;

把三个数字看作一个整体,设定为一个子模式,该子模式出现1次或以上时匹配成功。然而结果并没有改变,因为在replace中,+号是可有可无的。

接下来应该加什么限定条件,才可以令数字呈现3个一组,且不重复?是了,3个一组的数字是从字符串末尾开始计算的,那么加上一个结尾符如何?

var re3=/(?=(\d{3})+$)/g;//结果: 3,102,546,864

这个正则表达式的意思是寻找一个位置,该位置往后是1-n组,3个为一组的数字,且这些数字刚好截至到字符串的结尾(即找到数字的个数可以被3整除的一段了)

还有疑问吗?我们把具有迷惑性的g符去掉看看

var re4=/(?=(\d{3})+$)/;//结果: 3,102546864,可以知道确实是从目标位置开始界定了。刚才还在困惑正则表达式不是从前往后找吗,怎么倒可以从结尾数着3个一组?现在没有疑问了吧。

那么reg3的结果似乎已经OK了,是这样吗?如果数字的数量是3的倍数呢?

var s ="310254686";//结果却是 ,310,254,686 

位置的概念涵盖了开始位和结束位,现在我们要把开始位排除掉。

两个方法,一个是(?!^),另一个是\B

var regexp1=/\B(?=(\d{3})+$)/g;

var regexp12=/(?!^)(?=(\d{3})+$)/g;

最后就是 s.replace(regexp1,','),耶

这里可以测试正则表达式,超级棒

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

推荐阅读更多精彩内容

  • 什么是正则表达式 Regular Expression使用单个字符串来描述,匹配一系列符合某个句法规则的字符串 说...
    打铁大师阅读 775评论 1 6
  • 正则表达式练习题点击这里 创建一个正则表达式 使用一个正则表达式字面量,其由包含在斜杠之间的模式组成,如下所示: ...
    打铁大师阅读 1,243评论 0 6
  • 一.正则表达式匹配原则 占有字符和零宽度 在正则表达式匹配过程中,如果子表达式匹配到的是字符内容,并被保存在结果之...
    Coree阅读 523评论 0 0
  • 正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串...
    EarthChen阅读 349评论 0 0
  • 你想要的样子,你行动了吗?我的一个朋友说:“我想改变”,这几年我经常听她说这句话,今晚我又听到她说这句话!但我从来...
    大医美合伙人阅读 436评论 1 3