正则表达式

捕捉字符串的规律

正则表达式,意思是用来表示符合某种规则的式子,是用于匹配符合特定模式的字符串,也就是描述一类有特定规则的字符串。比如要在一篇文章中找到关于“xx大学”相关信息,如果既想找到“广州大学”的部分,也想找到“北京大学”的部分,直接搜索“大学”又可能会出现“青年大学习”这种无关信息,这时候通过正则表达式 [北|广][京|州]大学 就能查找“广州大学”和“北京大学”,当然副产品还有“广京大学”和“北州大学”。

正则表达式一般含有三种字符: 打印字符、非打印字符、特殊字符。

其中,一般打印字符和非打印字符只匹配一个字符位,如匹配 广州什么大学 的正则表达式 广州\S\S大学 中每个字符都只匹配对应的一个字符位。而特殊字符可以改变匹配的范围,从而允许匹配更多的字符位,如 广州什么什么大学广州大学 都能够使用 广州(.*)大学 来匹配,这是格式化匹配的关键。

在不同系统环境中,采用的正则表达规范或许会有所不同(BREs, EREs, PREs),这里不做细究。

打印/非打印字符

通俗来说,能看到的就是打印字符(包含空格在内),不能看到的用于控制(制表符、回车符等)或筛选某一类字符的就是非打印字符,参见 ASCII 码。

  • \n:换行符
  • \r:回车符
  • \s:空白符(大写 \S 为非空白)
  • \w:字母、数字或下划线(大写 \W 为非字)
  • \d:数字(大写 \D 为非数字)

特殊字符(元字符)

用于限定范围、限定匹配数量、限定位置等的特殊用途字符。匹配特殊字符需要转义,比如要匹配 * 则输入 \*

关于捕获元和非捕获元,个人猜测联想:用于匹配的子表达式就是捕获元,匹配到了就是捕获组,捕获组会保存起来供后续使用(如反向引用),而非捕获元匹配到的非捕获组不会保存起来,可能类似于宏定义和变量的区别。

限定范围(匹配一个字符位或子表达式):

  • ( ):括起来表示为子正则表达式,该子表达式可以用于其他特殊字符做进一步限定
  • [ ]:括起来表示限定范围在…之内,比如 [0-9][abcd][^abcd] 分别表示 0 到 9、abcd 之一、非 abcd 的任意字符。字符间默认用 | 分隔,如果想用“与”可以加入 &&,“非”则表示为 ^,范围表示似乎是以 ASCII 值做范围,似乎又字母大小写无关???(注意,匹配 [ ] 时需要转义,而匹配 - 需要非常谨慎对待,因为会随语言不同有不同约定,最好就写在最后面 [.&#_-],并经过测试 )
  • .:匹配除换行符 \n 外的任意单字符
  • |:二选一,匹配符号左边的字符串或符号右边的字符串

限定匹配数量(对象为前面的字符或子表达式):

  • +:匹配一次或多次(贪婪)
  • *:匹配零次或多次(贪婪)
  • ?:匹配零次或一次
  • {n}:匹配 n 次
  • {n,}:至少匹配 n 次
  • {n,m}:匹配 [n, m] 次

限定位置(表示匹配字符串出现的位置):

  • ^:限定在一行的开头,用在字符串开头
  • $:限定在一行的结尾,用在字符串结尾
  • \b:限定在单词边界,即字和空格之间,作为词首或尾用
  • \B:限定在非单词边界

非捕获元(接在表示子表达式的左括号后):

  • ?::表示该子表达式不会作为捕获组保存起来
  • ?=:正向预查,在 ?: 的基础上仅做预查,即匹配完后该子表达式不会被“消耗”,如 “ababa”,查 ab(?:a) 得到 “aba” 一个结果,而查 ab(?=a) 得到 “aba”、“aba” 两个结果
  • ?!:反向预查,就是正向预查的子表达式匹配取反,不匹配指定子表达式,同时是非捕获元
    • 如:搜查开头不为 xxxx 的任意行 (^(?!xxxx).*\n)+
    • 如:挑出两个 [Trial complete] 及其有用信息 units_4 ( \|-units_4: .*\n)(?:^(?!\[Trial complete\]).*\n)+(.*\n)\[Trial complete\]
  • ?<!:往前的反向预查,代表 “What’s before this is not…”

反向引用(匹配子表达式):

  • \1\99:引用捕获组保存的结果,为动态引用,匹配的结果左到右顺序保存到 1-99 缓冲区内。如 “frisk is frisk” 可用 (\w{3}) is \1 匹配 (VSCode 中反向引用为 $1

参考资料

基础:
https://www.runoob.com/regexp/regexp-syntax.html

非捕获元:
https://segmentfault.com/a/1190000010514763
https://www.jb51.net/article/79309.htm

测试:
https://regexr.com/

Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计