高性能的正则表达式效率优化

作者:小菜 更新时间:2025-02-26 点击数:
简介:前言编写高性能的正则表达式,有如下几条规则,这几条规则是本人总结出来的:1、使用正确的边界匹配器(^、$、\b、\B等)2、使用具体的元字符、字符类(\d、\w

【菜科解读】

前言

编写高性能的正则表达式,有如下几条规则,这几条规则是本人总结出来的:

1、使用正确的边界匹配器(^、$、\b、\B等)

2、使用具体的元字符、字符类(\d、\w、\s等)

3、使用正确的量词(+、*、?、{n,m})

4、使用非捕获组、原子组

5、注意量词的嵌套

其实正则表达式的很多优化技巧都是围绕着“减少回溯”这样一个原则进行优化的。

至于什么是“回溯”,笔者就不在这里重复了,以下通过具体的例子理解这样的过程。

示例

一、以下是一则匹配电子邮件地址的正则表达式:

^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$

先一步步的解析:

1、^\w+:表示必须以字符开始, 且是一个或者多个;

2、([\.-]?\w+)*中的“[\.-]?”表示匹配“.”或者“-”,零次或者一次;

3、([\.-]?\w+)*中的“\w+”则表示匹配一个或者多个的字符;

4、([\.-]?\w+)*整个则表示匹配.xxx、-xxx或者xxx这样的字符,且零次或者多次;

5、第1-4步,则匹配sunny或者sunny.yang这样的字符;

6、“@”则是具体元,匹配具体的@;

7、 \w+:则表示匹配的一个或者多个的字符,因为email不可能这样嘛:sunny@.gmail.com;

8、([\.-]?\w+)*:则跟第2-4步一样,匹配.163、-lib、.gd这样的字符,且零次或者多次;

9、(\.\w{2,3})+$:则匹配.com、.cc这样结尾的域名,且因为\w{2,3}限定了长度必须为2-3位,所以不能匹配.c、.n这样的字符。

乍看这样一个解析过程没问题,逻辑正确,但其实暗藏很多问题,看看以下的一个匹配图,backtrack则表示回溯(使用RegexBuddy可以很清晰的看到这过程)

整个成功的匹配过程经历了55步,我们先分析下整个匹配过程:

1、图中的第1和2步,匹配^\w+,匹配成功,匹配了“admin”;

2、图中第3步,匹配[\.-]?,当然由于不存在“.”和“-”,因此没匹配上具体的字符,但又由于“?”的限定,可以匹配零或者一次,因此这个子表达式匹配成功,虽然没匹配上具体的字符。

3、图中第4步,匹配\w+,由于“+”限定一个或者多个以上字符,但后续已经没[a-zA-Z0-9]可以匹配了,因此产生回溯,回溯到上次匹配成功的位置,也就admin;

4、图中第5步,因为上一步产生了回溯,所以“[\.-]?\w+”匹配了零次,由于([\.-]?\w+)*中限定零次或者多次,因此也匹配成功,也没匹配上具体的字符;

以下步骤,匹配该过程:

^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$

5、图中第6步,匹配了“@” ,第7步匹配了“\w+”,即匹配了“open”;

6、图中第8-13步,匹配“([\.-]?\w+)*” ,匹配了“-lib”、“.com”,匹配“.com”可能与我们期望不相符,我们期望这子表达式匹配的是www.xx.gd.cn中的“.gd”;

7、图中第7-10步,匹配了open-lib,第7-13步则匹配了open-lib.com;

8、因为“([\.-]?\w+)*”中的量词是“*”,则继续重复这个过程;

9、 图中第14步,匹配“([\.-]?\w+)*”中的“[\.-]?”,因为此时指针已经位于@open-lib.com之后了,但由于量词“?”,因此也匹配成功,但没匹配上字符,也没字符可匹配;

10、 图中第15步,匹配“([\.-]?\w+)*”中的“\w+”,此时指针仍位于字符串末尾,没任何字符能匹配,所以匹配失败,产生回溯,回到上次成功的位置,即图中的第13步,继续下个表达式的匹配;

11、 图中第16步,匹配(\.\w{2,3})+中的“\.”,由于没有任何字符能匹配,匹配失败,进行回溯;

12、图中第17步 ,(\.\w{2,3})+中量词“+”,表示该表达式必须匹配一次或者多次,由于上一步匹配失败了,所以匹配零次,但不符合一次或者多次的限定,因此继续回溯;

13、由于上一步匹配失败,需要进行回溯,因此表达式没有更多的分支了,只能将指针回退一个字符,回溯上次成功的位置,即([\.-]?\w+)*中\w+的位置(这是上次产生分支的位置);

14、图中剩下的步骤,就重复着匹配([\.-]?\w+)*,回退字符,匹配(\.\w{2,3})+这样的过程,直到匹配成功。

二、以下看看另外一则同样匹配邮件地址的正则表达式:

^\w+([-\.]\w+)*@\w+([-\.]\w+)*\.\w+([-\.]\w+)*$

这个正则跟上面的看起来貌似差不多,不过细看还是有区别的,也先一步步来解析:

1、^\w+:表示必须以字符开始, 且是一个或者多个(这一步与上面的一样);

2、([-\.]\w+)*中的“[-\.]”表示匹配“-”或者“.”;

3、([-\.]\w+)*中的“\w+”则表示匹配一个或者多个的字符;

4、([-\.]\w+)*整个则表示匹配.xxx、-xxx这样的字符,且零次或者多次;

5、第1-4步,则匹配sunny或者sunny.yang这样的字符;

6、“@”则是具体元,匹配具体的“@”;

7、 \w+:则表示匹配的一个或者多个的字符,因为email不可能这样嘛:sunny@.gmail.com;

8、([-\.]\w+)*:则跟第2-4步一样,匹配.163、-lib、.gd这样的字符,且零次或者多次;

9、“\.”则是具体元,匹配“.”;

10、\w+:则匹配一个或者多个字符;

11、([-\.]\w+)*:则匹配“.com”、“-lib”、“.c”这样的字符,且可以零次或者多次;

12、$:则表示结尾

乍看这个正则的步骤过程貌似比上一则长,其实不然,同时这个正则也存在着问题,先看看匹配图,同样backtrack表示回溯:

对的,你没看错,整个正确的匹配过程用了19步,对比前面的55步,简直天与地的差别。

,我们继续分析下匹配过程:

1、图中的第1和2步,匹配^\w+,匹配成功,匹配了“admin”;

2、图中第3步,匹配[-\.],当然由于不存在“.”和“-”,因此没匹配上具体的字符,也没具体的量词允许匹配零次,所以不用继续往下匹配了,因此直接产生了回溯;

3、图中第4步,因为上一步产生了回溯,所以“[-\.]\w+”匹配了零次,由于([-\.]\w+)*中限定零次或者多次,因此也匹配成功,也没匹配上具体的字符;

以下步骤,匹配该过程:

^\w+([-\.]\w+)*@\w+([-\.]\w+)*\.\w+([-\.]\w+)*$

4、图中第6步\w+,匹配了open;

5、图中第7-12步匹配([-\.]\w+)*,匹配了“-lib”和“.com”;

6、因为“([-\.]\w+)*”中的量词是“*”,则继续重复这个过程;

7、图第13步,匹配([-\.]\w+)*,因为此时指针已经位于@open-lib.com之后了,也没具体的量词允许匹配零次,因此匹配失败,回溯到上次成功的位置;

8、图第14步,匹配([-\.]\w+)*$中的“[-\.]”,此时指针仍位于字符串末尾,没任何字符能匹配,所以匹配失败,产生回溯,回到上次成功且还没尝试过的位置,即图中的第9步;

9、经过上面的回溯,指针已经位于@open-lib之后的位置了;

10、图第15步匹配了“.”,第16步\w+则匹配了“com” ;

11、图第17步匹配([-\.]\w+)*,由于此时指针又位于字符串末尾,因此[-\.]部分没匹配上任何字符,因此产生回溯;

12、图第18步,由于([-\.]\w+)*的量词是“*”,表示匹配零次或多次,虽然子表达式[-\.]匹配失败,所以整个表达式匹配了零次,也是匹配成功;

13、最后一步第19步,“$”表示末尾匹配,因为此时指针位于字符串末尾,故符合,因此也匹配成功。

分析

整个匹配过程关键优化地方,还是回溯,两个示例表达式看起来相近,匹配过程也部分类似,但两个例子的效率却如此大的分别,现在来分析一下造成回溯的原因。

对比下两个表达式不同的部分:

^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$

^\w+([\.-]\w+)*@\w+([\.-]\w+)*\.\w+([-\.]\w+)*$

高性能,的,正则,表达式,效率,优化,前言,编写,

传说中的妖祖、佛祖、魔祖、道祖,他们分别都是谁?谁的实力最强

妖祖、佛祖、魔祖、道祖是中国神话之中出现频次较高的称谓之一,代表着中国神话之中妖魔鬼怪各个阶级的最强战斗力。

那么,不少朋友就会感到好奇,古人是怎么确认和区分这些神话角色的,它们的来源又有什么故事,最重要的是,这些神话角色的战斗力又如何呢?妖祖竟是创世神,人类都要叫她母亲在这些称谓之中,妖祖可能是我们接触最少,感到最为陌生的一个称号了。

但这位称号持有者我们可一点都不陌生:在中国神话之中,被称为妖祖的,正是我们熟知的那个补天造人的女娲。

根据山海经的记载,虽然女娲是仅次于盘古诞生的第二位神,但她本身是人身蛇尾的妖精,手持一柄万妖幡,号令天下妖精。

相传只要女娲一声令下,挥动手中的万妖幡,整个世界的妖精都会听从女娲的调令,帮助女娲四处征战。

作为中华民族创世神话之神,女娲在我们心中的地位自然也是不低。

除了能够号令天下所有妖精之外,女娲还有能够创造一个种族的能力,能赋予他人生命力,是神话中对于一个神明最高的崇敬,由此可见女娲的实力。

而且在后来流传的传说之中,天地由于灾难破损大开,女娲为了拯救人类而用尽自己能力收集补天石去补天,能够仅凭一人之力,改变天地状态,女娲的实力不容小觑。

也是因为如此壮举,更是确立了女娲在中华神话之中的地位,她虽然是妖王,但也能够成为万人敬仰的中华神话主神之一。

佛祖到底是谁,竟然有好几个?对我们来说,最熟悉的称号可能就是佛祖了,我们以“佛祖保佑”挂在嘴边,那么佛祖的能力又如何呢?很多人看见佛祖二字,脑海中第一反应就是释迦摩尼。

其实将释迦摩尼与佛祖画等号这种说法不完全正确,虽然在历史上佛教确实为释迦摩尼所创立,但在佛教神话之中,释迦摩尼只代表着我们现代这个时代的“佛祖”。

神话中记载,在释迦摩尼成为佛祖前,人们将燃灯佛供奉为佛祖,所以我们称呼“燃灯佛”为“过去佛”。

在燃灯佛的时代结束后,释迦摩尼接过了佛祖的称号,成为了“现世佛”,也就是我们如今口中的佛祖。

而在释迦摩尼完成使命后,我们熟悉的另一位佛陀——弥勒佛接过他的位置,成为未来的佛祖,因此弥勒也被称为“未来佛”。

那么佛祖的实力如何呢?大千佛法,功德无量,备受世人崇敬的释迦摩尼实力自然是不容小觑,但释迦摩尼平日从不轻易出手,所以我们很难直接看出佛祖的战力。

但从西游记这类故事中可以侧面看出,令神仙们头疼不已的弼马温,被释迦摩尼在须臾之间就压在了五指山下,五百年动弹不得,可见佛祖的实力绝非小可。

道祖有人间化身,而且写在我们的教科书里道教为我们中国本土宗教,其思想内核蕴含着许多中华文化的儒家哲理。

道教的影响力虽逊色于佛教,但道教至尊,被称为道祖的太上老君更是一直被我们尊崇着,可以说单从受尊敬的程度上来说,太上老君甚至要比佛祖影响力大。

虽然太上老君不是道教神话之中地位最高的神仙,他的身份比王母玉帝稍微低一些,可太上老君的实力和影响力却完全盖过这两位神仙。

在神话之中,太上老君除了拥有呼风唤雨,召唤神兽,散布祥瑞的能力之外,他的战力也不容小觑。

《五千文经序》中记载描述,太上老君不受时间限制,不受空间限制,也不受任何物理控制,太上老君既有形,也无形,是世间大道的综合。

而在史实之中,我们通常会将老子看做是道祖的化身,是太上老君在人间的代表。

老子作为我国古代重要的思想家,其影响力不言而喻,撰写的《道德经》规范了后世人们的生活。

上至帝王下至百姓,都在老子提出的思想指导之下生息着,“无为而治”的概念甚至影响了我们现代人的生活,甚至写进了我们的教科书中。

由此可见,道祖无论是在神话之中还是在史实之中,都具有非常强大的影响力。

无形化身赋予了道祖几乎无尽的战斗能力,无为而治的思想又赋予道祖他人无法比拟的思想能力,可谓是这四祖中的顶尖翘楚。

#p#分页标题#e#魔祖战斗力最弱?他可是战神关于魔祖究竟是谁,历史中有很多争议,也引起了广泛的讨论,但是多数人公认的魔祖就是熟悉的蚩尤。

至于蚩尤是如何成为魔祖的,历史上有两个解释,一个是因为蚩尤长相可怖,旁人见到后都会战栗发抖,产生恐惧,以为蚩尤是魔物到了凡间,便称其为魔祖。

另一种解释是,因为蚩尤与炎黄二帝在涿鹿中原的战争之中杀了太多人,手中沾染了太多无辜之人的鲜血,因此在被称为战神的同时,也被冠以了“魔祖”的称号。

最终蚩尤大败于炎黄联军之手,两位皇帝彰显自己的正义,以及夺取中原后的正统,自然也就将魔祖这个称号流传下来了。

作为魔祖,蚩尤的战斗力同样是十分惊人的,凭一人之力,带领自己的部族对抗炎黄二帝的联军,并且在缺兵少粮,自己领地天灾不断的情况下,能够与两位大帝打的有来有回。

首先蚩尤指挥能力毋庸置疑,毕竟是中华民族公认的战神,凭借一己之力吞并了数百个部族。

而在战争中,炎黄二帝也是赌上了性命,费尽艰辛才将蚩尤斩杀,蚩尤本人战力可见一斑。

但可惜的是,虽然蚩尤是魔祖,可仍然是一介凡人,战斗力也就只能够到达凡人的天花板,是无法和上文几个神仙相比的。

因此,如果单纯将这几位的战力相比较的话,实力最弱的便是魔祖,而女娲因为没有撼天动地的能力,只能被动修补天地而排在魔祖之后。

再之后是佛祖,虽然佛祖有无上功德,法力无边,但是因为佛祖有可替换性,在位不稳定,因此排第二。

所以,实力最强的就是道祖太上老君,无形之力囊括世间万物,不可替代性也确保无人能够接替老君的位置,因此太上老君的实力在四人之中排第一。

可神话与史诗都需要结合各位神仙所处的环境来看,虽然蚩尤实力最弱,但是在中华神话之中,他也是不可或缺的战神,备受敬仰。

而女娲造人和补天是其他神仙无法替代的壮举,佛祖功德无量,引世人向善。

太上老君作为中华文明精神的引路人而被世代传颂,若是比较功绩,那这几位的功德孰优孰劣,就难说了。

念一遍就有灵验的咒语民间最灵的法术

  民间最灵的法术 特灵验。

最灵的咒语一念就有效,从前古人比较迷信咒语,以为通过几句咒语就能掌握一个人的生老病死。

现在大部分都已经意识到这不过是封建迷信,是不可信的。

不过现在民间还流传着一些咒语。

今天小编介绍一下古老民间最灵的108个咒语 在古代人们都不懂科学,一个人生病死亡,就认为是有人诅咒的。

  民间最灵的法术 特灵验 最灵的咒语一念就有效  高僧一念咒语对方就昏死,此人不信说:让我来试试,结果高僧死了  "南朝四百八十寺,多少楼台烟雨中。

"这两句诗相信很多人都听说过,它出自于唐代著名诗人杜牧的《江南春》,一句话写出了南朝寺庙之多。

南朝即魏晋风流之后的南北朝时期,由于佛法的兴盛,当时的帝王大多提倡佛教,修建了大量的与佛教相关的寺庙塔阁。

  除了皇帝之外,他的后妃、公主兴造寺塔之风也特别的兴盛。

因此南朝寺院林立,且以木材构筑者居多,绝大部分佛寺皆在都城建康。

  根据清朝刘世琦所作《南朝寺考·序》:"梁世合寺二千八百四十六,而都下(南京)乃有七百余寺。

" 其中尤以同泰寺、瓦官寺、栖霞寺较为著名。

  而这股风气并没有随着南朝的覆灭,隋唐两朝的相继建立而消失,反而有愈演愈烈之势。

比如唐太宗时期的大和尚玄奘西游天竺取真经就是一个很典型的事件,除了中原地区之外,崇尚佛法的这股风气还传到了日本,如鉴真东渡弘扬佛法,让许多的日本人来到中原地区学习先进佛法经验。

  当然了,有人弘扬佛教,自然就有人反对佛教,而唐朝的著名学者傅奕就是其中的一位。

  根据《新唐书》记载,"(傅奕)相州邺人。

通晓天文历数。

初仕隋,入唐为太史丞,后迁太史令。

进《漏刻新法》,行于时。

又注《老子》,撰《老子音义》。

曾多次上谏禁除佛教,并将魏、晋以来斥佛言论编集成《高识传》十卷。

"  傅奕为什么这么强烈反对佛教,除了他本身是儒学和道学两派的代表人物之外,更重要的是,佛教经过南朝几百年的发展,已经良莠不齐,龙蛇混杂,很多人打着佛教的旗号到处招摇撞骗,欺骗无知群众的钱物财产,带来了很恶劣的社会影响。

  曾经有一个西域来的番僧,据说擅长咒术,能够通过自己的咒语让人马上死去,不仅如此,还能够让死去的人立马复活。

这个番僧在大街上表演了好几次之后,蒙骗了好多人,最后连唐太宗也知道了。

加入收藏
               

高性能的正则表达式效率优化

点击下载文档

格式为doc格式

  • 账号登录
社交账号登录