-
-
最实用的RegExp(正则表达式)技巧
-
发表于: 2018-5-31 21:41 4301
-
我并不经常使用RegExp,一旦需要,我会使用多种方法。
注意:此博客文章使用JavaScript作为示例,但并不是只有JavaScript才可以使用这些技巧。
我们时常需要从一大段文本中提取出带引号的字符串、HTML标签或是大括号之间的内容。尽管写一些适当的分析程序会使代码更加健壮、更易于维护和可读,但我们经常选择正则表达式(或简称RegExp),因为你只需要搜索现成的RegExp并使用它就行。你在网络上找到的基于RegExp的解决方案都不是最优的,并且很难读懂它们的工作原理。
让我们来看一下提取字符串的例子;你面临的情况可能是,需要从一段 JavaScript中,提取出带引号的字符串:
刚接触到RegExp的人可能会想是/".*"/gus完成了提取工作,让我们来仔细分析这个RegExp的含义:
/…/gus ——在JavaScript(以及许多其他语言)中RegExp以斜线分隔,后跟模式标志。g表示在同一个字符串中可能有多个匹配,我们对它们都感兴趣。u能够将模式视为Unicode,这通常来说更有意义;s允许.匹配\n。
" ——匹配一个"字符
. ——匹配任何字符
* ——重复最后一次操作符0次或多次
" ——再一次匹配一个"字符
注意:在JavaScript中,s和u都是相当新的标志,可能不是所有的浏览器都会支持。
在我们的输入字符串中运行这个RegExp会产生一个意想不到的结果: "Hello world!"); console.log("Hello back!" 这就是计算机“在技术上是正确的”的情况——这个字符串两端确实有引号,并且在这之间确有一段的任意字符,但并没有达到我们想要的效果。
我最经常看到的解决方案是人们切换到“non-greedy”模式*:
这里的RegExp和上面那个相似,但是它却让*通配符尽量少的去匹配字符(即non-greedy,非贪婪模式),以此来得到我们期望的结果.
就个人而言,我对非贪婪模式的匹配存在信任问题,更关键的是:在console.log("Hello \"world\"!");上运行正则表达式会发生什么呢?
显然没有达到效果。
反斜杠背叛了我们!所以现在怎么办?这就是我即将要说的诀窍了,我将我的RegExp告诉你,而且会向你展示我是如何做到的:/"([^"\\]|\\.)*"/gus
没错,我们只是用了RegExp中的一个,漂亮不?
第一个问题是,虽然/".*?"/gus能够起一点作用,但还是没能达到我们的目的。我们并不想得到双引号间的任何字符,只需要双引号。如何做到这一点呢?在RegExps中,你可以使用字符组来匹配整个字符集:
[abc]——匹配所包含的任意一个字符,如a,b,c;
[a-z]——匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符;
[^abc]——匹配除a,b,c外的任何字符;
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课