如何看懂“铁路图”

由 Regexper-CHS 生成的图像一般叫做“铁路图”(Railroad Diagrams)。这些图是一种直观的方式,用来表示正则表达式中可能变得非常复杂的处理过程,例如嵌套循环和可选元素。阅读这些图表最简单的方法是从左到右沿着线路进行。如果遇到分支,则可以选择沿着其中一条路径前进(这些路径可能会循环回到图表的较早部分)。要使某个字符串成功匹配图表所表示的正则表达式,你必须从左到右依次满足图表中的每个部分,并一直推进到图表的终点。

例如,右侧图形显示的正则表达式可以匹配 "Lions and tigers and bears. Oh my!" 或更符合语法的 "Lions, tigers, and bears. Oh my!"(无论是否使用牛津逗号)。 在展示的铁路图中,首先必须匹配字符串 "Lions",如果输入中没有这个字符串,就无法继续。接下来,有一个选择分支,可以匹配逗号 "," 或字符串 " and"。无论选择哪条路径,输入字符串接下来都必须包含 " tigers",然后是一个可选的逗号(路径可以选择经过逗号或绕过它)。最后,字符串必须以 " and bears. Oh my!" 结尾。

铁路图的基础组成部分

铁路图中最简单的部分是那些匹配特定文本且没有可选项的部分。这些包括:

字面字符(Literals)

字面字符(Literals),用于匹配精确的文本字符串。它们以浅蓝色框显示,并且内容会被引号括起来(以便更清晰地查看开头或结尾的空格)。

转义序列(Escape sequences)

转义序列(Escape sequences)以绿色框显示,并包含对它们所能匹配字符类型的描述。

任意字符(Any Character)

任意字符(Any Character)的功能类似于转义序列,它可以匹配任意单个字符。

字符集(Character Sets)

字符集用于匹配或不匹配一组指定的字符。它以方框形式显示,其中包含字面字符和转义序列。顶部的标签表明该字符集将匹配“其中之一”(One of)包含的字符,或“均不匹配”(None of)包含的字符。

子表达式(Subexpressions)

子表达式通过虚线框标记其包含的表达式元素。

其中:捕获型子表达式(Captured subexpressions)会标注其对应的捕获组编号;正向先行断言(Positive lookahead),如:?=pattern 和负向先行断言(Negative lookahead),如:?!pattern 会直接标明类型。

选择分支(Alternation)

选择分支为正则表达式提供多个可选项,其表现形式为:表达式路径展开成多个分支,每个分支代表一个可能的匹配选项。

量词(Quantifiers)

量词用于指定表达式的某部分是否应重复匹配或作为可选匹配。在正则表达式图示中,量词的表示方式与选择分支(Alternation)类似,路径会分叉并可能形成循环(即回退到自身)。 除非路径上有箭头明确指示方向,否则默认优先选择直行路径(即非贪婪匹配)。

零次或多次量词(Zero-or-more Quantifier)

贪婪量词
非贪婪量词

零次或多次量词(Zero-or-more Quantifier),该量词(符号:*)会匹配任意次数(包括零次)的重复模式。

译注:该量词是正则表达式中通用性最强的重复匹配工具,但需注意其贪婪性可能导致的性能问题(如回溯过多)

必需量词(Required Quantifier)

贪婪量词
非贪婪量词

必需量词(Required Quantifier),该量词(符号:+)会匹配至少一次或多次的重复模式。与零次或多次量词(*)不同,它不允许跳过匹配——模式必须至少出现一次才能成功。

可选量词(Optional Quantifier)

贪婪量词
非贪婪量词

可选量词(Optional Quantifier),该量词(符号:?)会匹配零次或一次的重复模式,且不允许循环匹配(即不能重复多次)

范围量词(Range Quantifier)

贪婪量词
非贪婪量词

范围量词(Range Quantifier)该量词(符号:{min,max} 空格敏感,不正确的空格会导致解析失效)用于指定匹配模式可以重复的次数。这里提供的两个示例范围都是"{5,10}",循环分支上的标签表示该分支可以被循环的次数。这些数值比表达式中指定的少1,因为模式必须先匹配一次,然后才能选择是否重复。因此,对于这些示例,模式会先匹配1次,然后循环跟随4到9次,最终实现模式总共匹配5到10次。