Java 正则表达式多重分组

Java 正则表达式多重分组,java,regex,regex-group,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 final Matcher m = Pattern.compile("s[0-9]{1,2}e([0-9]{1,2

我正试图制作一个节目来组织我的电视节目集

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

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

“s01e01.avi”预期结果=1

“s01e01和s01e02.avi”预期结果=1,2

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

“s01e03.04 s01e05.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));
    }
}
“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));
    }
}
final Matcher m=Pattern.compile(“s[0-9]{1,2}([0-9]{1,2})(\\\[0-9]{1,2})*”).Matcher(文件名);
while(m.find()){
对于(int i=1;i
这就是我得到的,但它只适用于每组只有一集的情况:

工作

“s01e01.avi”结果:1,正确

“s01e01和s01e02.avi”结果:1,2,正确

不工作

“s01e01.02.avi”(仅与第一次出现的匹配,本例中为1)预期结果:1,2

“s01e01.02 s01e03.04.avi”(仅与每组的第一次匹配,本例中为1和3)预期结果:1,2,3,4

非常感谢您抽出时间来

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

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

(?为什么不

e(\d\d)\.?(\d\d)?
只要你没有任何名为“The55 show”或类似的电视节目,它就不会中断。将在比赛的分组中捕获集号

.

为什么不

e(\d\d)\.?(\d\d)?
只要你没有任何名为“The55 show”或类似的电视节目,它就不会中断。将在比赛的分组中捕获集号


.

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

因此,虽然您编写了一个循环来查找以
s
开头的每个部分做得很好,但您仍然存在一个问题,即以
s
开头的部分本身可能包含一系列的插曲编号。虽然您可以找到一种巧妙的方法来使用单个循环,但我建议使用嵌套的
find
循环,或者<代码>拆分
。您的第一个模式应如下所示:

final Matcher m = Pattern.compile("s[0-9]{1,2}e([0-9]{1,2}(?:\\.[0-9]{1,2})*)").matcher(fileName);
请注意,匹配多次出现的内容(如
.02
.03
等)的部分已移动到第一个捕获组中。(我将
?:
放在第二组括号中,以强调这是而不是
将使用
组()提取的捕获组的事实。
)执行此操作后,
组(1)
的结果可能是
“01”
“01.02”
“03.04.05”
或其他任何内容。现在可以按句点字符拆分:

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

注意:这是一种通常适用于类似类型问题的方法。您的特定问题非常简单,只需一个循环即可解决(因为组合
\d\d
不会出现在任何其他地方,除非出现在
S\d\de……
模式中),但在某些情况下,这种方法将不起作用。

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

因此,虽然您编写了一个循环来查找以
s
开头的每个部分做得很好,但您仍然存在一个问题,即以
s
开头的部分本身可能包含一系列的插曲编号。虽然您可以找到一种巧妙的方法来使用单个循环,但我建议使用嵌套的
find
循环,或者<代码>拆分
。您的第一个模式应如下所示:

final Matcher m = Pattern.compile("s[0-9]{1,2}e([0-9]{1,2}(?:\\.[0-9]{1,2})*)").matcher(fileName);
请注意,匹配多次出现的内容(如
.02
.03
等)的部分已移动到第一个捕获组中。(我将
?:
放在第二组括号中,以强调这是而不是
将使用
组()提取的捕获组的事实。
)执行此操作后,
组(1)
的结果可能是
“01”
“01.02”
“03.04.05”
或其他任何内容。现在可以按句点字符拆分:

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

注意:这是一种通常适用于类似类型问题的方法。您的特定问题非常简单,只需一个循环即可解决(因为组合
\d\d
不会出现在任何其他地方,除非出现在
S\d\de……
模式中),但也会有这种方法不起作用的情况。

问题是,OP已经将问题读了两遍。@Kent已修复。仍然没有必要匹配
s..
部分。问题是如果你“合法获取”一集,名字真的是一团糟,所以我想要一个更准确的正则表达式:很多时候我看到像“P0se1don.avi的s01e03”(波塞冬内部的e1将打破正则表达式)问题是,OP有
s01e03.04
请把问题读两遍。@Kent修复了。仍然没有必要匹配
s.
部分。问题是,如果你“合法地获得”一集,名称真的是一团糟,所以我想要一个尽可能准确的正则表达式:很多时候我看到像“s01e03 by P0se1don.avi”这样的东西(波塞冬内部的e1将破坏正则表达式)您基本上使用的是与我相同的正则表达式…我不知道为什么,但它不起作用…尝试类似于s01e01.02的东西。03@Spotlight好吧,你没有把它放在例子里,我想是abo