我正在尝试使用Ruby中的正则表达式来分解标准的RESTful URI。
假设我们正在制作音乐唱片网络应用程序。我们有很多艺术家,有很多专辑,有很多歌曲。
使用此设置,以下RESTful URI应全部作为GET请求提供:
/artists
/artists/1
/artists/1/albums
/artists/1/albums/1
/artists/1/albums/1/songs
/artists/1/albums/1/songs/1
/artists/1/albums/1/songs/1/artists
/artists/1/albums/1/songs/1/artists/1
为了尝试使用Regexp捕获这些URI,我掀起了以下内容(live example):
^\/(?<resource>(?:artists|albums|songs))(?:\/(?<id>\d+))?\/?$
当给出如下所述的根级资源时,正则表达式按预期工作:
/artists
/songs/1
第一个生成的匹配数据的资源为artists
,ID为nil
,第二个资源为songs
,ID为1
。
但是当给定一个请求资源关联的URI时,例如/albums/1/songs/1
,此正则表达式将失败,因为如果不考虑递归。所以,我把整个事情扔进了一个非捕获组,上面有一个或多个(+
)限定符:
^(?:\/(?<resource>artists|albums|songs)(?:\/(?<identifier>\d+))?)+\/?$
此正则表达式现在适用于/albums/1/songs/2
等URI,但生成的匹配数据仅包含最后一个资源(songs
)和id(2
)。
我期待一个包含两个对象的数组,一个资源为albums
,另一个资源为songs
。
在使用“一个或多个”限定符的捕获组中是否有正确使用命名捕获的方法?
答案 0 :(得分:0)
大多数正则表达式都不会那样。每个捕获组仅包含它匹配的最后一个子字符串。 除非您使用.NET regex lib,它会记住捕获组的每个匹配项。
答案 1 :(得分:0)
“递归”对于你遇到的问题来说并不是一个正确的词。您正试图在正则表达式中迭代多个/resource/id
对,然后检索单个捕获。我建议你改用这个正则表达式:
\/(?<resource>artists|albums|songs)(?:\/(?<identifier>\d+))?
...并迭代代码中的/resource/id
对(例如,使用scan
方法)。