首页 > 解决方案 > 为什么我的命名捕获组不起作用?

问题描述

假设我有一个代表电影的文件名列表。每部电影肯定有一个标题和一个文件扩展名,但每个文件名可以包含 0-3 个标签列表。一个标签列表是一对括号括起来的逗号分隔的标签;标签以%(对于系列/特许经营名称)、@(对于人员)或#(对于描述性标签)开头,并且每种类型都在自己的列表中。它们总是在文件扩展名之前,它们之间没有空格,并且总是按顺序出现(%series,%series)(@person,@person)(#tag,tag)。例子:

我的目标是编写一个带有命名捕获组的正则表达式title, serieslist, peoplelist, 并taglist帮助我巧妙地提取所有这些。

当它们都存在时我可以管理它,但是在使它们成为可选时我很困惑,这是一个难以理解的大表达式,很难解析。

这是我迄今为止的最大努力。它匹配所有标签列表,并且在缺少任何标签列表时都很好......但前提是标题后有空格。标题匹配组后面有一个空格,所以这是有道理的。但是,如果我从正则表达式中删除该空间,那么所有其他组都会失败,我不明白为什么。我忽略了一些愚蠢的事情吗?这是我想念的懒惰/贪婪的东西吗?

(?<title>.+) (?:\((?<series>%[^)]+)?\))?(?:\((?<people>@[^)]+)?\))?(?:\((?<tags>#.+)\))?(?<extension>\.[^.]+)$

这是我的 Regex101 页面,在“切换到单元测试”选项卡上有一组单元测试,希望这些比我的描述更有意义。

非常感谢任何可以帮助我认识到我的错误的人。

标签: javascriptregex

解决方案


您可以使用此正则表达式:

(?<title>.+?)[ ]*(?:\((?<series>%[^)]+)\)|\((?<people>@[^)]+)\)|\((?<tags>#[^)]+)\))*(?<extension>\.[^.]+)$

正则表达式 101 上的演示

系列、人物和标签捕获组被交替放置,然后重复以允许对这 3 个项目进行灵活排序。这将允许名称中有多个标签,但只捕获最后一个。


推荐阅读