正则表达式多重分组

时间:2014-09-13 21:52:20

标签: java regex regex-group

我正在尝试制作一个整理我的电视节目集的节目。

我的正则表达式需要根据剧集的文件名识别剧集编号。请注意,有时单个视频文件包含更多剧集。

在我的特定情况下,我只需要解析名为:

的剧集

" s01e01.avi"预期结果= 1

" s01e01& s01e02.avi"预期结果= 1,2

" s01e01.02.avi"预期结果= 1,2

" s01e03.04 s01e05.06.avi"预期结果= 3,4,5,6

" s01e03.04.05.06.avi"预期结果= 3,4,5,6

final Matcher m = Pattern.compile("s[0-9]{1,2}e([0-9]{1,2})(\\.[0-9]{1,2})*").matcher(fileName);
while(m.find()) {
    for (int i = 1; i < m.groupCount(); i++) {
        System.out.println("myEpisodeNumer = " + m.group(i));
    }
}

这就是我所拥有的,但它仅适用于每组只有一集的情况:

WORKS

&#34; s01e01.avi&#34;结果:1,正确

&#34; s01e01&amp; s01e02.avi&#34;结果:1,2,正确

不要工作

&#34; s01e01.02.avi&#34; (仅匹配第一次出现,在本例中为1)预期结果:1,2

&#34; s01e01.02 s01e03.04.avi&#34; (仅匹配每个组的第一个匹配项,在本例中为1和3)预期结果:1,2,3,4

非常感谢你的时间

3 个答案:

答案 0 :(得分:3)

试试这个:(没有调整以适应java语法)

(?<=s\d\de)(\d\d)|(?<=\d\d[.])(\d\d)*

此处示例:查看捕获的组:

http://regex101.com/r/jH3yZ5/4

答案 1 :(得分:2)

为什么不

e(\d\d)\.?(\d\d)?

只要您没有任何名为“The55 show”的电视节目或类似节目,它就不会破坏。剧集编号将在比赛组中捕获。

See it in action here

答案 2 :(得分:1)

问题是单个正则表达式无法轻松返回值列表。 (即使您在捕获组之后放置*+,也不会导致添加更多捕获组;捕获组的数量是固定值,仅基于模式,而不是源字符串。)

因此,虽然您编写循环以查找以s开头的每个部分,但仍然存在问题,即以s开头的部分可能自身包含列表剧集编号。虽然您可以通过单个循环找到一种棘手的方法,但我建议您使用嵌套的find循环或split。你的第一个模式应如下所示:

final Matcher m = Pattern.compile("s[0-9]{1,2}e([0-9]{1,2}(?:\\.[0-9]{1,2})*)").matcher(fileName);

请注意,匹配多个事件(如.02.03等)的部分已移至第一个捕获组内。 (我将?:放在第二组括号中,以强调这是一个您将使用group()提取的捕获组。)执行此操作后, group(1)的结果可能是"01""01.02""03.04.05"或其他。现在您可以拆分句点字符:

while (m.find()) {
    for (String episode : m.group(1).split("\\.")) {
        System.out.println("myEpisode = " + episode);
    }
}

P.S。这种方法通常适用于类似的问题。您的特定问题很简单,只需一个循环即可解决(因为组合.\d\d不会发生在除s\d\de.......模式之一之外的任何其他地方),但会出现这种情况不会工作。