正则表达式百科全书,做NLP或者其他处理的时候再也不怕和字符串混淆了。在这篇文章中,作者从基础到高级介绍了很多正则表达式,而这些表达式或规则在很多编程语言中都是通用的。正则表达式(regex或regexp)对于从文本中提取信息非常有用,并且通常搜索与特定模式匹配的语句,例如特定的ASCII或Unicode字符序列。从解析/替换字符串、预处理数据到网络抓取,正则表达式可用于广泛的应用程序。其中一件比较有趣的事情是,只要我们学会了正则表达式的语句,我们几乎可以将它们应用到很多编程语言中,包括JavaScript、Python、Ruby和Java。只是每种编程语言所支持的顶层特性和语法有细微的差别。下面我们可以详细讨论一些案例和解释。一、基本语句1、锚点:^和$^The匹配任何以“The”开头的字符串->Tryit!(https://regex101.com/r/cO8lqs/2)end$匹配以“end”开头的字符串提取字符串末尾的^Theend$匹配从“The”到“end”结尾的字符串。Roar匹配任何带有文本“roar”的字符串2.量词:*、+、?和{}abc*匹配“ab”后跟零个或多个“c”字符串->试试吧!(https://regex101.com/r/cO8lqs/1)abc+匹配"ab"后跟一个或多个"Thestringabc?ofc"匹配字符串abc{2,}of"ab"后跟一个或一个"c"匹配"ab"后跟两个"c"的字符串abc{2,}"ab"后跟两个或多个"c"字符串abc{2,5}匹配"ab"后跟2到5"c"stringsa(bc)*在"a"之后匹配字符串a(bc){2,5}后跟零个或多个"bc"序列匹配字符串3后跟"a"后跟2到5"bc"序列。或运营商:|,[]a(b|c)匹配“a”后跟“b”或“c”->试试吧!(https://regex101.com/r/cO8lqs/3)a[bc]匹配“a””后跟“b”或“c”4.字符类:\d、\d、\s和.\d匹配数字类型的单个字符->Tryit!(https://regex101.com/r/cO8lqs/4)\w匹配一个单词(字母加下划线)->试试吧!(https://regex101.com/r/cO8lqs/4)\s匹配单个空格字符(包括制表符和换行符)。匹配任何字符->Tryit!(https://regex101.com/r/cO8lqs/5)使用“.”运算符需要非常小心,因为常见或排除的字符类都更快且更精确\d、\w和\s也有它们各自的排除字符类,\D、\W和\S。例如,\D将执行与\d完全相反的操作:\D匹配单个非数字字符->Tryit!(https://regex101.com/r/cO8lqs/6)为了正确匹配,我们必须使用转义字符反斜杠“\”定义我们需要匹配的符号“^.[$()|*+?{\",因为我们可能会认为这些符号在原文中有特殊的含义。\$\d匹配在单个数字前带有符号“$”的字符串->Tryit!(https://regex101.com/r/cO8lqs/9)注意我们也可以匹配不可打印的字符,比如制表符“\t”、换行符“\n”和回车符“\r”5.标志我们已经学习了如何构建正则表达式,但我们仍然错过了一个非常基本的概念:标志。正则表达式通常以/abc/的形式出现,其中搜索模式由两个反斜杠“/”分隔。在模式的最后,我们通常可以指定以下标志配置或它们的组合:g(global)在第一次匹配后不会返回结果,它会继续搜索其余文本。m(多行)允许使用^和$来匹配一行的开头和结尾,而不是整个序列。i(insensitive)使整个表达式不区分大小写(例如/aBc/i将匹配AbC)。2.中间语句1.分组捕获:()a(bc)括号会创建一个捕获分组,会捕获匹配项"bc"->Tryit!(https://regex101.com/r/cO8lqs/11)a(?:bc)*使用"?:"会使捕获组失效,只需要匹配前面的"a"->Tryit!(https://regex101.com/r/cO8lqs/12)a(?bc)使用"?"将为组配置一个名称->Tryit!(https://regex101.com/r/cO8lqs/17)捕获括号()和非捕获括号(?:)对于从字符串或数据中提取信息非常重要,我们可以在不同的编程语言中执行此操作,例如Python。从多个组中捕获的多个匹配项将在一个经典数组中表示:我们可以使用匹配结果的索引来访问它们的值。如果我们需要给组添加一个名称(使用(?...)),我们可以像字典一样使用匹配结果检索组的值,其中字典的键就是组的名称。2.括号表达式:[][abc]匹配带有“a”、“ab”或“ac”的字符串->与a|b|c相同->Tryit!(https://regex101.com/r/cO8lqs/7)[a-c]匹配一个带有“a”、“ab”或“ac”的字符串->与a|b|c相同[a-fA-F0-9]匹配一个代表十六进制数的字符串,caseinsensitive->Tryit!(https://regex101.com/r/cO8lqs/22)[0-9]%匹配%符号前的0到9一串字符[^a-zA-Z]匹配没有a到z或A到Z的字符串,其中^是否定表达式->Tryit!(https://regex101.com/r/cO8lqs/10)请记住,在方括号内,所有特殊字符(包括反斜杠\)将失去其应有的含义。3.GreedyandLazy匹配量词(*+{})是一个贪心运算符,所以他们会遍历给定的文本,尽可能匹配。例如,<.+>将匹配文本“Thisisasimplediv
test”中的“simplediv
”。为了只捕获div标签,我们需要使用“?”使贪婪搜索有点懒惰:<.+?>匹配“<”和“>”中的任何字符一次或多次,并且可以根据需要扩展->Tryit!(https://regex101.com/r/cO8lqs/24)注意更好的解决方案应该避免使用“.”,这有利于实现更严格的正则表达式:<[^<>]+>onceorMatchanycharacterin多次使用“<”和“>”,删除“<”或“>”字符->试试吧!(https://regex101.com/r/cO8lqs/23)3.进阶语句1.边界字符:\b和\B\babc\b进行全词匹配搜索->Tryit!(https://regex101.com/r/cO8lqs/25)\b表示一个像插入符一样的锚点(它与$和^相同)来匹配一侧是单词符号(例如\w)而另一侧不是单词的位置符号(例如,它可能是字符串或空格符号的起点)。它还可以表示相反的非单词边界“\B”,它会匹配“\b”不会匹配的地方,如果我们想找到被单词字符包围的搜索模式,就可以使用它。只要\Babc\B被单词字符包围,就会匹配->Tryit!(https://regex101.com/r/cO8lqs/26)2.正向匹配和反向匹配:(?=)和(?<=)d(?=r)仅当后跟“r”时才会匹配“d”,但“r”不会成为整个正则表达式匹配的一部分->Tryit!(https://regex101.com/r/cO8lqs/18)(?<=r)d只会匹配前面有“r”的“d”,但“r”不会成为整个正则表达式匹配的一部分->Tryit!(https://regex101.com/r/cO8lqs/19)我们还可以使用否定运算符:d(?!r)仅当“d”后面没有跟“r”时才匹配“d”,但“r”不会成为整个正则表达式匹配的一部分->Tryit!(https://regex101.com/r/cO8lqs/20)(?***Tryit!*(https://regex101.com/r/cO8lqs/21)4.结论如上所示,正则表达式的应用领域非常广泛。读者在开发过程中很可能遇到过。以下是正则表达式常用的字段:数据校验,比如检查时间字符串是否符合格式;数据抓取,以特定顺序抓取包含特定文本或内容的网页;数据包装,将数据从一种原始格式转换为另一种格式;字符串解析,例如捕获拥有的URL的GET参数,或捕获一组括在括号中的文本;字符串替换,将字符串中的一个字符替换为另一个字符。原文链接:https://medium.com/factory-mind/regex-tutorial-a-simple-cheatsheet-by-examples-649dc1c3f285【本文为微信《机器之心》专栏原文翻译♂《机器之心(id:almosthuman2014)》】点此查看该作者更多好文