我试图从一个逗号分隔列表中检索匹配,该列表位于括号内,使用正则表达式。(我还检索了第一个捕获组中的版本号,尽管这对这个问题并不重要)
值得注意的是,表达式应该理想地处理所有可能的情况,其中列表可以是空的,或者在第二个捕获组中有超过3个条目=0或更多匹配项。
我现在的表达方式如下:
SomeText\/(.*)\s\(((,\s)?([\w\s\.]+))*\)
我正在测试的字符串如下所示:
SomeText/1.0.4 (debug, OS X 10.11.2, Macbook Pro Retina)
其结果是:
1. [6-11] `1.0.4`
2. [32-52] `, Macbook Pro Retina`
3. [32-34] `, `
4. [34-52] `Macbook Pro Retina`
期望的结果如下所示:
1. [6-11] `1.0.4`
2. [32-52] `debug`
3. [32-34] `OS X 10.11.2`
4. [34-52] `Macbook Pro Retina`
根据上面的图像(据我所见),表达式应该在测试字符串上工作。导致这种奇怪结果的原因是什么,我如何改进表达方式?
我知道解决这个问题还有其他方法,但如果可能的话,我想使用一个正则表达式。请不要提出其他选择。
发布于 2016-01-15 15:55:34
也许G锚在这里最适合将匹配绑定到入口点。这个正则表达式是为输入而设计的,它总是类似于在您的问题中提供的示例。
(?<=SomeText\/|\G(?!^))[(,]? *\K[^,)(]+
(?<=SomeText\/|\G)
回头看是匹配应该粘到的部分\G
匹配上一次匹配结束的(?!^)
,但不匹配开始[(,]? *\
匹配可选的开头括号或逗号,后面跟着任意大小的空格。[^,)(]+
匹配被通缉的字符,这些字符都不是(
)
,
regex101演示 ($0
的抓取匹配)
使用俘获群的另一个想法。
SomeText\/([^(]*)\(|\G(?!^),? *([^,)]+)
这个不需要查找的方法更准确一些(它还需要括号),性能更好(需要更少的步骤),并且可能更容易理解和维护。
SomeText\/([^(]*)\(
条目锚点和版本在这里捕获到$1
|\G(?!^),? *([^,)]+)
或粘贴到以前的匹配:捕获到$2
中的一个或多个字符,这些字符不是,
)
前面的可选空格或逗号。发布于 2016-01-15 15:15:29
当处理不同数量的组时,regex并不是最好的。分两步解决。
首先,使用简单的正则表达式分解语句:
SomeText\/([\d.]*) \(([^)]*)\)
1. [9-14] `1.0.4`
2. [16-55] `debug, OS X 10.11.2, Macbook Pro Retina`
然后,只需explode
的第二个结果,由',得到你们的小组。
发布于 2016-01-15 16:58:54
实际上,斯特里比佐夫很接近:
(?:SomeText\/([^() ]*)\s*\(|(?!^)\G),?\s*([^(),]+)(?=[^()]*\))
只需要让那一类人至少有一场比赛
只要版本号始终是数字和句点,(?:SomeText\/([0-9.]+)\s*\(|(?!^)\G),?\s*([^(),]+)(?=[^()]*\))
就会更清楚一些。
https://stackoverflow.com/questions/34813937
复制相似问题