尝试将这些输入字符串匹配到三个匹配组(Regex101链接):
| input string | x | y | z |
------------------------------------
I | a | a | | |
II | a - b | a | b | |
III | a - b-c | a | b-c | |
IV | a - b, 12 | a | b | 12 |
V | a - 12 | a | | 12 |
VI | 12 | | | 12 |
Run Code Online (Sandbox Code Playgroud)
所以输入字符串的解剖结构如下:
- 可选的第一部分,带有自由文本,直到
hyphen带有周围的空格(-)或输入字符串结束- 可选的第二部分,在第一个连字符后面有任何字符,周围有空格,直到a
comma或输入字符串结束- 最后可选两个数字
我尝试过多种不同的解决方案,这是我目前的尝试:
^(?P<x>.*)(?:-)(?P<y>.*)(?<!\d)(?P<z>\d{0,2})(?!\d)$
Run Code Online (Sandbox Code Playgroud)
它处理场景II,IV然后V确定(必须对白色空间进行一些修整),但是:
I并且VI根本不归还III 不是在第一个连字符处分开,而是在最后一个连字符处分开这看起来相当不错:
^(?:(.*?)(?: - |$))?(?:(.*?)(?:, |$))?(\d\d$)?$
Run Code Online (Sandbox Code Playgroud)
感兴趣的值将分别在第1,2和3组中.
唯一的罪魁祸首是"两位数"
在这些情况下,其他群体是空的.
这是因为"两位数"很乐意匹配"自由文本直到分隔符或字符串结束"规则.
您可以使用负向预测强制将两个数字强制转换为最后一个组,但除非"两个数字"不是第1组和第2组的合法值,否则这将不正确.在任何情况下,它都会使表达方式变得笨拙:
^(?:((?!\d\d$).*?)(?: - |$))?(?:((?!\d\d$).*?)(?:, |$))?(\d\d$)?$
Run Code Online (Sandbox Code Playgroud)
分解:
^ # string starts (?:(.*?)(?: - |$))? # any text, reluctantly, and " - " or the string ends (?:(.*?)(?:, |$))? # any text, reluctantly, and ", " or the string ends (\d\d$)? # two digits and the string ends $ # string ends
| 归档时间: |
|
| 查看次数: |
774 次 |
| 最近记录: |