笔记:正则表达式

曾经一直以为正则表达式(Regular Expression或Regex)过于复杂,无谓地增加程序阅读的复杂度,所以没有认真看过正则表达式的用法。在编程时,用一般的字符串操作函数,完全能够实现正则表达式的功能。最近,在CodeWars进行编程练习,遇到很多字符串匹配的问题。练习相关的几道题后发现,使用正则表达式解决字符串匹配类的问题,代码更加简洁、高效。因此,开始看正则表达式相关的资料,希望以后在CodeWars上能用得到。

正则表达式是一种特殊的字符串,用于描述一种字符串的模式,匹配一组(多个、很多个)字符串。比如,[tr]est是一个正则表达式,能够匹配testrest两个字符串。

正则表达式:[tr]est
字符串模式:字符串的第1个字符为t或T,第2个字符为e,第3个字符为s,第四个字符为T

字符串匹配是正则表达式最基本的功能。正则表达式需要一种正则引擎才能实现这样的功能。正则引擎是一种解析正则表达式的程序,它以正则表达式和普通字符串为输入,然后在普通字符串中搜索,判断其中是否存在字符串满足正则表达式所描述的模式。

普通字符、特殊字符、字符集合和字符组

字符是字符串的基本组成元素。正则表达式也是一种字符串,所以第一步就要讨论组成正则表达式的基本元素。普通字符就是特殊字符以为的字符,比如a-zA-Z0-9、@!$%`等。一些不可打印的字符也可以归为普通字符。普通字符的特点是,一个普通字符就表示它本身;对于可打印字符,用户看见什么就代表什么;对于不可打印字符,就算用户看不见,它还是那个字符本身。

特殊字符是在正则表达式中不再是字符本身,而具有特定意义。比如[tr]est中,[]不表示中括号,而是构成一个字符集合。正则表达式的特殊字符包括[]\^$.|?*+{}\是转移字符,如果普通字符中包含上述特殊字符,需要在特殊字符前添加转移字符。.表示任意字符。

[]中所有字符组成一个字符集合。正则表达式中,字符集合出现的位置可以是所有字符中任意一个字符。比如[abcdef]string中,[abcdef]位于第1个字符的位置,因此如果一个字符串与该正则表达式匹配,它的第1个字符可以是abcdef的任意一个。有意思的是,字符集合中很多特殊字符会被当成普通字符处理,只有^\-还具有特殊意义。^表示字符集合的逆;\还是表示转义;-表示连续的字符段,比如a-z表示所有13个小写的字母。

()中所有字符组成一个子正则表达式,可以当成把它一个整体看待。如果后面添加重复操作符,()会被当成一个整体进行重复。

位置匹配

某些匹配问题对字符串所处的位置也有一定的要求,比较常用的有起始位置、结束位置。
整个单词的匹配也是与位置相关匹配,即字符串位于单词的边界之间。

  • ^: 标记字符串的起始位置;
regex start label

虽然标记为1This和标记为2This由相同的字符组成,但是它们所处的位置有所不同。前者位于整个字符串的起始位置,后者则不是。如果只想匹配位于起始位置的字符串,需要使用^。因此,正则表达式^This会匹配标记为1This

  • $:标记字符串的结束位置;
regex end label

虽然标记为1string和标记为2string由相同的字符组成,但是它们所处的位置有所不同。后者位于整个字符串的结束位置,前者则不是。如果只想匹配位于结束位置的字符串,需要使用$。因此,正则表达式string$会匹配标记为2string

  • \b: 标记单词的边界。
regex word boundary

标记为1is和标记为2is的不同在于,前者是单词This的一部分,而后者是单独组成一个单词。在整词匹配过程中,使用正则表达式\bis\b,只有标记2is满足要求,其中\b用于标记单词的边界。

单词的边界位置有4种情形:

1. 如果字符串不以字母字符开始,那么第一个字符前面位置是单词边界,比如'p1'位置。
2. 如果字符串不以字母字符结束,那么最后一个字符后面是单词边界,比如'p4'位置。
3. 非字母字符之后,字母字符之前为单词边界,比如'p2'位置。
4. 字母字符之后,非字母字符之前也为单词边界,比如'p3'位置。

重复字符/字符串

  • *:前一个字符或字符串重复0次或多次。正则表达式abc*能够匹配ababcabccabccccc等字符串;
    正则表达式z(abc)*能够匹配zzabczabcabczabcabcabc等字符串。
  • +:前一个字符或字符串重复1次或多次。
  • ?:前一个字符或字符串重复0次或1次。
  • {min,max}:前一个字符或字符串重复min至max次。

混合正则表达式

  • |:用于组合多个正则表达式。regex1|regex2能够在字符串中同时匹配regex1regex2

条件判断正则表达式

  • (?(?=regex)then|else)

如果if部分能够匹配,正则引擎会尝试匹配then部分;否则,尝试匹配else部分。

  • (?(?=condition)(then1|then2|then3)|(else1|else2|else3))

参考资料

推荐阅读更多精彩内容

  • 推荐几个正则表达式编辑器 Debuggex :https://www.debuggex.com/ PyRegex:...
    杨梦鸽阅读 8,088评论 10 150
  • 几个正则表达式编辑器 Debuggex :https://www.debuggex.com/ PyRegex:ht...
    没技术的BUG开发攻城狮阅读 3,263评论 0 23
  • 正则表达式到底是什么东西?字符是计算机软件处理文字时最基本的单位,可能是字母,数字,标点符号,空格,换行符,汉字等...
    狮子挽歌阅读 683评论 0 9
  • 1、正则表达式使用的特殊符号和字符 1.1、用管道符号( | )匹配多个正则表达式模式,即或,匹配多个表达式。 例...
    大婶N72阅读 72评论 0 0
  • 秋风清,秋月明, 落叶聚还(huán)散,寒鸦栖复惊。 相思相见知何日?此时此夜难为情! 入我相思门,知我相思苦,...
    柳翠阅读 77评论 0 0