正则表达式基础

2021-02-19 04:15:56

在我的团队中,我们每两周举办一次“大师班”,团队中的某人向团队的其他成员介绍一个主题。

本文基本上是我最近提供的有关正则表达式(也称为regex)的类的内容。

介绍正则表达式的基础知识。有很多类似的东西,但这是我的。

它们基本上在每种编程语言中都可用,并且您可能最经常会遇到它们,它们用于条件匹配中的字符串匹配,这些条件对于简单的逻辑比较(例如“或”,“和”,“中”)而言过于复杂。

‘有些人遇到问题时,会想:“我知道,我会使用正则表达式。”现在他们有两个问题。’–杰米·扎温斯基(Jamie Zawinski)

在编程中,只能将正则表达式用作最后的选择。不要用正则表达式解决重要问题。

正则表达式很昂贵–正则表达式通常是程序中CPU占用最大的部分。不匹配的正则表达式可能比匹配的正则表达式更昂贵。

regex贪婪–匹配比预期的要容易得多,从而导致bug。我们多次遇到正则表达式过于贪婪的问题,从而在我们的网站中引起了问题。

regex是不透明的–即使非常了解regex的人也要花一些时间来挑选新的regex字符串,并且仍然可能会犯错误。从长远来看,这将对项目维护产生巨大的成本。 (查看此惊人的正则表达式以获取RFC822电子邮件地址)

始终尝试了解操作和检查字符串时可以使用的所有语言功能,这可以帮助您避免使用正则表达式。例如,在Python中,可以非常有效地组合使用in关键字,强大的[]索引以及诸如contains和startswith的字符串方法(可以为多个值提供元组字符串)。

最重要的是,不应将正则表达式用于解析字符串。您应该改用或编写定制的解析器。例如,您不能使用正则表达式解析HTML(在Python中,使用BeautifulSoup;在JavaScript中,使用DOM)。

当然,有时可以在程序中使用正则表达式:

当它已经存在并且必须维护时(尽管可以删除它,但应该)

如果您正在编写除最基本的正则表达式之外的任何内容,那么任何维护人员都不太可能轻易理解您的正则表达式,因此您可能要考虑添加自由注释。例如。在Python中:

>>> pattern =""" ^#字符串的开头M {0,4}#千位-0到4 M' s(CM | CD | D?C {0,3})#百-900(CM),400(CD),0-300(0到3 C' s),#或500-800(D,然后是0到3 C&#39s)(XC | XL | L?X {0,3})#十进制-90(XC),40(XL),0-30(0至3 X&s),#或50-80(L,然后是0至3 X& #39; s)(IX | IV | V?I {0,3})#1-9(IX),4(IV),0-3(0至3 I&#39s),#或5 8(V,后跟0到3个I)$#字符串的末尾"""> re.search(样式,' M&#39 ;, re.VERBOSE)

正则表达式对于快速解决自己的问题非常有用,因为将来无需担心维护问题。例如。:

还值得抓住机会以这些方式使用正则表达式来练习正则表达式技能。

例如,我最近在VSCode中使用以下正则表达式替换将文本转储格式化为表格式:

请记住,正则表达式解析器有几种形式。基本上,每种语言都实现自己的解析器。但是,Perl的正则表达式解析器是黄金标准。如果可以选择,请使用Perl兼容的正则表达式。

这就是用Perl和JavaScript以及Less等许多命令行工具编写它们的方式。

但是,更多现代语言(例如Python)选择不包含本机正则表达式类型,因此正则表达式可以简单地写为字符串:

前一个字符可能存在也可能不存在(例如/ hell?o /会匹配hello或helo) 允许使用任意数量的前面的字符(例如。*将与任何单行字符串(包括空字符串)匹配,并被大量使用) 前面的一个或多个字符(。+与。*相同,只不过它不匹配空字符串) “或”,匹配上一部分或下一部分(例如hello | mad将匹配“ hello”或“ mad”) 将部分分组。 这对于条件((a | b)),乘数((hello)+)或为替换创建组很有用(请参见下文) 指定多少个前面的字符(例如a {12}连续匹配12个“ a”) 匹配此集合中的任何字符。 -定义范围(例如[a-z]是任何小写字母),^表示“不”(例如[^,] +连续匹配任意数量的非逗号)

在大多数正则表达式实现中,可以将反斜杠后跟字母(\ x)用作字符集的快捷方式。以下是rexegg.com的regex备忘单中一些常见的清单。

编程中正则表达式最简单的用例是字符串比较。这在不同的语言下看起来有所不同,例如:

您还可以使用正则表达式通过替换操作字符串。在以下示例中,将打印出“疯狂的世界”:

您可以基于一些修饰符来更改正则表达式的行为。我将在这里举例说明,它是使regex不区分大小写的修饰符。在Perl,JavaScript和其他更传统的正则表达式上下文中,修饰符添加在最后一个/之后。更现代的语言通常使用用户常量代替:

这些仅在正则表达式的某些实现中受支持,并且使您有机会匹配其他字符串之前或之后的字符串,但在匹配本身中不包括前缀或后缀:

这就是我现在所拥有的。如果您想了解更多信息,这里有很多有用的资源:

iHateRegex –示例regex模式的集合,用于匹配某些常见类型的字符串(例如电话号码,电子邮件地址)