正则表达式常用的语法(正则表达式应该怎么学)
学习正则表达式最好的方式是读《精通正则表达式》这本书:
《精通正则表达式》
建议认真学完前6章,后面与具体编程语言相关的可以跳过。花一些时间系统地学习一下正则表达式是非常有好处的。就像张无忌学会九阳神功后学其他武功都特别快,学会正则表达式后再学习UNIX/Linux的下的工具也都特别快!
除了推荐书籍,我也分享一下我自己读写正则表达式的心得。
如何读正则表达式?《精通正则表达式》这本书让我认识到,正则表达式只是一种描述字符串长什么样的声明式语言,是字符串的元信息。就像SQL是用来描述数据长什么样的声明式语言,只是SQL使用更直观的英文单词作为关键词,而正则表达式使用的是更加精炼但也更加晦涩的符号字符。
所以,学习正则表达式与学习其他语言的过程是一样的,需要学会这门语言的词法、语法、语义。如果对这些词法、语法、语义不熟悉,看正则表达式就像天书一样。
词法
如前文所述,正则表达式的单词由标点符号字符组成。和汉语、英语等自然语言一样,这些单词也有词性,包括字符(character)、字符类(character class)、分组(grouping)、量词(quantifier)、锚点(Anchor)等。
想要一股脑记住所有符号及其含义,就像从头到尾背英语词典一样,是很低效且痛苦的。好在正则表达式的单词也符合2-8法则,就像英语里的常用词一样并不多,诸如零宽断言等用法其实不太常用,用到的时候临时查文档复习一下用法就行。
以下几个字符是最最常用的元字符:
单词 |
词性 |
语义 |
^ |
锚点 |
以……开头 |
$ |
锚点 |
以……结尾 |
. |
字符集 |
任意字符 |
* |
量词 |
任意多个 |
|
量词 |
1个或多个 |
? |
量词 |
0个或1个 |
需要注意的是,除了惰性匹配的量词,其他量词默认都是贪心匹配,即尽可能多地匹配、直到无法匹配为止。
语法
正则表达式的语法并不多,除了要开闭括号要能一一对应,也就是量词只能放在字符、字符集、分组的后面。
示例
举个例子:
/^ab c*$/
该模式读作:“有一些字符串,它们以1个a开头,紧接着1个或多个b,最后以任意多个c结尾。”符合这个规则的字符串很多,有“ab”、“abc”、“abbccc”等等。
如何写正则表达式?有了前文读正则表达式的基础,基本上也能照葫芦画瓢写正则表达式了,但新手在写正则表达式的时候往往容易忽略“上下文”,会写出非常具体、非常长的模式。因为正则表达式的主要用途就是用于文本匹配,所谓的“上下文”就是正则表达式预计在那些文本中匹配。上下文不同,解法也可以不同。
举个例子,一个爬虫爬取到以下HTML页面信息:
<html>
<body>
<header>
<nav>
<ol>
<li><a href="/">Home</a></li>
<li><a href="/friends">Friends</a></li>
</ol>
</nav>
</header>
<main>
<ul class="friends">
<li class="name">Bob</li>
<li class="name">William</li>
<li class="name">Vina</li>
</ul>
</main>
</body>
</html>
假设希望在这些内容中匹配出包含「朋友姓名」的行,比较简单的方式有:
/class="name"/
还能更简洁一些:
/name/
或者更具体一些:
/<[Ll][Ii]\s class="[^"]*\bname\b[^"]*">[^<>] <\/[Ll][Ii]>/
这三种方式哪种最好呢?这个得视情况而定。我的建议是:
如果数据来源比较可控,例如内部系统生成的数据,则尽量写简单有效的模式;
如果数据来源不可控,例如网络爬虫从外部系统抓取的数据,内容随时都有可能发生变化,那适度地优化一下正则表达式,让模式具备一些弹性去适应可预见的一些变化。
如果让我来写这个例子的正则表达式,我会倾向于这样写:
/class="[^"]*\bname\b[^"]*"/
这样既具备一定的弹性,例如未来添加了其他class,或li换成其他tag,都能自动适应;又不会过于复杂。
综上所述,正则表达式并没有唯一的标准答案,需要根据待匹配文本的上下文选择复杂度最合适的方案。因此,写正则表达式时不用着急,不必要求自己一次就写对。应该像写SQL一样在数据集上多select几次,对数据集有了较全面的认知后,不断修正数据过滤条件,就能优化出比较精炼的SQL;同样的,写正则表达式也是在目标字符串上反复筛选,最后就能优化出比较精炼的模式。
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com