0

我正在尝试使用 Ruby 中的正则表达式来分解标准的 RESTful URI。

假设我们正在开发一个音乐唱片 Web 应用程序。我们有很多艺术家,有很多专辑,有很多歌曲。

使用此设置,以下 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,我制作了以下内容(现场示例):

^\/(?<resource>(?:artists|albums|songs))(?:\/(?<id>\d+))?\/?$

当给定如下的根级资源时,正则表达式按预期工作:

/artists
/songs/1

第一个结果匹配数据的资源为artists,id 为nil,第二个匹配数据的资源为songs,id 为1

但是,当给定一个请求资源关联的 URI 时,例如/albums/1/songs/1,此正则表达式将失败,因为 if 不考虑递归。所以,我把整个东西放在一个非捕获组中,+上面有一个“一个或多个”( ) 限定符:

^(?:\/(?<resource>artists|albums|songs)(?:\/(?<identifier>\d+))?)+\/?$

此正则表达式现在适用于 URI,/albums/1/songs/2但生成的 matchdata 仅包含最后一个资源 ( songs) 和 id ( 2)。
我期待一个包含两个对象的数组,一个资源为albums,一个资源为songs.

有没有办法在使用“一个或多个”限定符的捕获组中正确使用命名捕获?

4

2 回答 2

0

大多数正则表达式风格都不是这样工作的。每个捕获组将只包含它匹配的最后一个子字符串。除非您使用 .NET 正则表达式库,它会记住捕获组的每个匹配项。

于 2012-04-07T15:19:50.603 回答
0

“递归”并不是您遇到的问题的正确词。您正在尝试在您的正则表达式中迭代多个/resource/id对,然后检索各个捕获。我建议你改用这个正则表达式:

\/(?<resource>artists|albums|songs)(?:\/(?<identifier>\d+))?

...并遍历/resource/id代码中的对(例如,使用scan方法)。

于 2012-04-07T16:15:58.437 回答