捕获重复正则表达式捕获组的部分

时间:2015-11-29 22:52:19

标签: regex .htaccess

^([a-z-]+-on-sale(?:,[a-z-]+-on-sale){0,})[\/]$

此正则表达式用于htaccess文件并匹配此类模式:

tools-on-sale,candy-on-sale,food-on-sale/

我一直想知道是否有可能捕获重复捕获组的子部分。我想匹配相同的模式,但我想省略重复捕获组中的“-on-sale”部分。我知道我已经可以在正则表达式的第一部分做到这一点:

^(([a-z-]+)-on-sale(?:,[a-z-]+-on-sale){0,})[\/]$

这样我就可以在自己的捕获组中分离出“工具”,但我似乎无法对第二部分做同样的事情。这是否可以使用正则表达式?

2 个答案:

答案 0 :(得分:1)

如果我认为我理解你,你想获得一份 on-sale 的清单?

您已经知道如何捕获第一个工具 但是,你需要一场比赛。

好消息是只有 Dot-Net 可以在捕获集合中执行此操作 像这样:

 # ^((?:(?:^|(?<!^),)(?<sale_item>[a-z-]+)-on-sale)+)[\/]$

 ^     
 (                             # (1 start)
      (?:
           (?:
                ^ 
             |  (?<! ^ )
                , 
           )
           (?<sale_item> [a-z-]+ )       # (2)
           -on-sale 
      )+
 )                             # (1 end)
 [\/] $

其中 sale_item 是一个列表。

坏消息是,在所有其他正则表达式引擎上,
整体匹配将是相同的,但 sale_item 捕获缓冲区
覆盖量化组的每次迭代 因此, sale_item 将仅包含 last 项“food”。

答案 1 :(得分:1)

实现这一目标并不是一个简短的方法。但是,您可以定义应该期望的最大数量的项目,并为每个项目创建一个可选组。

对于1到3件物品:

^([a-z-]+)-on-sale(?:(,[a-z-]+)-on-sale(?:(,[a-z-]+)-on-sale)?)?/$

请求网址

http://foo.bar/tools-on-sale,candy-on-sale,food-on-sale/

<强> htaccess的

RewriteRule ^([a-z-]+)-on-sale(?:(,[a-z-]+)-on-sale(?:(,[a-z-]+)-on-sale)?)?/$ http://foo.bar/$1$2$3 [L]

*感谢@sln建议改进

输出网址

http://foo.bar/tools,candy,food

但是,如果您需要除逗号以外的分隔符,则如果您的项目少于3个,则会生成空标记。 E.g:

http://foo.bar/tools--

如果必须避免,则需要为每个项目创建1条规则:

RewriteRule ^([a-z-]+)-on-sale,([a-z-]+)-on-sale,([a-z-]+)-on-sale/$ http://foo.bar/$1-$2-$3 [L]
RewriteRule ^([a-z-]+)-on-sale,([a-z-]+)-on-sale/$ http://foo.bar/$1-$2 [L]
RewriteRule ^([a-z-]+)-on-sale/$ http://foo.bar/$1 [L]