【发布时间】:2012-04-07 14:18:56
【问题描述】:
我正在尝试使用 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,我创建了以下内容 (live example):
^\/(?<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+))?)+\/?$
此正则表达式现在适用于 /albums/1/songs/2 等 URI,但生成的匹配数据仅包含最后一个资源 (songs) 和 id (2)。
我期待一个包含两个对象的数组,一个资源为albums,一个资源为songs。
有没有办法在使用“一个或多个”限定符的捕获组中正确使用命名捕获?
【问题讨论】:
-
有些人在遇到问题时会想“我知道,我会使用正则表达式。”。现在他们有两个问题。
-
有些人在遇到正则表达式时会想“我知道,我会使用我记得的引人入胜的引语”。现在他们没有在讨论中添加任何内容。 -- Tomalak
-
无论如何,这只是我对人们滥用正则表达式的直觉反应。 --MДΓΓ БДLL。