折叠并捕获单个正则表达式中的重复模式

折叠并捕获单个正则表达式中的重复模式

我不断遇到需要从字符串中捕获大量令牌的情况,经过无数次的尝试后,我找不到简化过程的方法。

所以我们说文本是:

启动:测试 - 测试 - LOREM-存有-SIR-doloret - 等 - 等 - 的东西:结束

这个例子里面有8个项目,但是说它可能有3到10个项目。

我理想上喜欢这样的东西:
start:(?:(\w+)-?){3,10}:end漂亮而干净但是它只能抓住最后一场比赛。看这里

我通常在简单的情况下使用这样的东西:

start:(\w+)-(\w+)-(\w+)-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?:end

由于最大10限制,3组强制要求和另外7组可选,但这看起来并不“好”,如果最大限制为100且匹配更复杂,编写和跟踪将是一件痛苦的事。演示

到目前为止我能做的最好:

start:(\w+)-((?1))-((?1))-?((?1))?-?((?1))?-?((?1))?-?((?1))?-?((?1))?:end

特别是如果比赛很复杂但仍然很长。演示

有人设法让它作为一个没有编程的1正则表达式解决方案工作

我最感兴趣的是如何在PCRE中完成,但其他口味也可以。

更新:

目的是match 0通过RegEx单独验证匹配并捕获单个令牌,而不受任何OS /软件/编程语言限制

更新2(赏金):

在@nhahtdh的帮助下,我使用以下方法访问下面的RegExp \G

(?:start:(?=(?:[\w]+(?:-|(?=:end))){3,10}:end)|(?!^)\G-)([\w]+)

演示甚至更短,但无需重复代码即可进行描述

我也对ECMA的味道感兴趣,因为它不支持\G想知道是否有另一种方式,特别是不使用/g修饰符。


开满天机
浏览 661回答 3
3回答

一只斗牛犬

虽然理论上可以编写单个表达式,但首先匹配外部边界然后在内部部分执行拆分更加实用。在ECMAScript中,我会这样写:'start:test-test-lorem-ipsum-sir-doloret-etc-etc-something:end'     .match(/^start:([\w-]+):end$/)[1] // match the inner part     .split('-') // split inner part (this could be a split regex as well)在PHP中:$txt = 'start:test-test-lorem-ipsum-sir-doloret-etc-etc-something:end';if (preg_match('/^start:([\w-]+):end$/', $txt, $matches)) {     print_r(explode('-', $matches[1]));}
打开App,查看更多内容
随时随地看视频慕课网APP