【问题标题】:Java Regex - Probable error while defining capturing groupsJava Regex - 定义捕获组时可能出现错误
【发布时间】:2020-12-05 16:32:38
【问题描述】:

Correction of an algorithm for String analysis 的伪续集。阅读链接对于理解问题是不必要的,但它提供了上下文。

我的目标是从满足正则表达式的字符串中提取捕获组的内容。我的问题是(显然)我没有正确识别/定义捕获组。

在下面提供的示例中,正则表达式是^[A-Za-z0-9][A-Za-z0-9] s(?<season>[A-Za-z0-9])e(?<episode>[A-Za-z0-9]) [A-Za-z0-9].mp4。这(理论上)应该是任何字符串都满足的正则表达式:

  • 一个随机的(甚至是无效的)前缀;
  • 后跟字符串 s
  • 后跟多个字母数字字符(命名组season);
  • 后跟字符串e
  • 后跟多个字母数字字符(命名组episode);
  • 后跟字符串 (一个简单的空格);
  • 后跟随机(甚至是空)字符串;
  • 后跟字符串.mp4;

理论上,下面代码的小sn-p应该筛选输入字符串(Star Wars Rebels s02e18 - The Forgotten Droid.mp4)并将02识别为命名组season的值,并将18识别为episode的值。相反,我收到了 java.lang.IllegalStateException: No match found 错误消息。最糟糕的是,在修改代码使其显示命名组的名称后,似乎有 no 命名组。我很困惑。

我做错了什么?定义命名组有问题吗?在matcher.group(...) 方法中召回它们?正则表达式写错了吗?

公平警告:这是我第一次使用 Java 正则表达式,因此可能存在多个问题。


代码:

String regex = "^[A-Za-z0-9][A-Za-z0-9] s(?<season>[A-Za-z0-9])e(?<episode>[A-Za-z0-9]) [A-Za-z0-9].mp4";
String string = "Star Wars Rebels s02e18 - The Forgotten Droid.mp4";
        
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(string);
        
System.out.println("\t\t pattern: " + pattern.toString() + "\n\t\t Named groups: ");
for(int i=0 ; i<matcher.groupCount() ; i++)
    System.out.println("\t\t\t Group " + i + "-th: " + matcher.group(i));
        
System.out.println("Season value: " + matcher.group("season"));
System.out.println("\t Episode value: " + matcher.group("episode"));

【问题讨论】:

  • 您没有重复字符类,并且像这样使用锚^ 将阻止模式匹配,因为在示例字符串中之前有文本要匹配。试试^.*?[A-Za-z0-9]{2} s(?&lt;season&gt;[A-Za-z0-9]+)e(?&lt;episode&gt;[A-Za-z0-9]+) - .*[A-Za-z0-9]\.mp4$regex101.com/r/2l6ik6/1
  • 你从来不允许matcher真正搜索通过调用find()方法来匹配正则表达式的部分文本,也不能检查正则表达式是否真的matches() 整个 字符串(取决于您的意图)。请退后几步阅读有关如何在该语言中使用 regex 引擎的 java 教程。
  • 使用 matcher.find 的示例ideone.com/eTfLm2

标签: java regex regex-group


【解决方案1】:

一些从字符串中提取季节和剧集的替代正则表达式

备选方案 1 - 定义组名:

"\\w+\\s+s(?<season>\\d+)e(?<episode>\\d+).*\\w+\\.mp4"

在上下文中查看替代 1 正则表达式:

public static void main(String[] args) {
    String input = "Star Wars Rebels s02e18 - The Forgotten Droid.mp4";

    // From the input the following is matched: 'Rebels s02e18 - The Forgotten Droid.mp4'
    String regex = "\\w+\\s+s(?<season>\\d+)e(?<episode>\\d+).*\\w+\\.mp4";
    Matcher matcher = Pattern.compile(regex).matcher(input);

    // The condition have to be true before using "matcher.group()",
    // or 'java.lang.IllegalStateException: No match found' will be thrown.
    if(matcher.find()) { 
        // Output: 'Season value:  02'
        System.out.println("Season value:\t" + matcher.group("season"));
        // Output: 'Episode value: 18'
        System.out.println("Episode value:\t" + matcher.group("episode"));
    }
}

备选方案 2 - 没有组名,匹配整个输入:

"^\\S+\\s.*?\\ss(\\S+)e(\\S+).*\\S+\\.mp4"

上下文:

public static void main(String[] args) {
    String input = "Star Wars Rebels s02e18 - The Forgotten Droid.mp4";

    // From the input the following is matched: 'Star Wars Rebels s02e18 - The Forgotten Droid.mp4'
    String regex = "^\\S+\\s.*?\\ss(\\S+)e(\\S+).*\\S+\\.mp4";
    // MULTILINE due to Boundary matcher '^'
    Matcher matcher = Pattern.compile(regex, Pattern.MULTILINE).matcher(input);

    // The condition have to be true before using "matcher.group()",
    // or 'java.lang.IllegalStateException: No match found' will be thrown.
    if(matcher.find()) {
        String season = matcher.group(1);
        String episode = matcher.group(2);
        // Output: 'Season value:  02'
        System.out.println("Season value:\t" + season);
        // Output: 'Episode value: 18'
        System.out.println("Episode value:\t" + episode);
    }
}

备选方案 3:

"^\\w+\\s.+?\\ss(?<season>\\w+)e(?<episode>\\w+).*\\w+\\.mp4"

上下文:

public static void main(String[] args) {
    String input = "Star Wars Rebels s02e18 - The Forgotten Droid.mp4";

    // From the input the following is matched: 'Star Wars Rebels s02e18 - The Forgotten Droid.mp4'
    String regex = "^\\w+\\s.+?\\ss(?<season>\\w+)e(?<episode>\\w+).*\\w+\\.mp4";
    // MULTILINE due to Boundary matcher '^'
    Matcher matcher = Pattern.compile(regex, Pattern.MULTILINE).matcher(input);

    // The condition have to be true before using "matcher.group()",
    // or 'java.lang.IllegalStateException: No match found' will be thrown.
    if(matcher.find()) {
        // Output: 'Season value:  02'
        System.out.println("Season value:\t" + matcher.group("season"));
        // Output: 'Episode value: 18'
        System.out.println("Episode value:\t" + matcher.group("episode"));
    }
}

备选方案 4:

"^[A-Za-z0-9]+\\s.+?s(?<season>[A-Za-z0-9]+)e(?<episode>[A-Za-z0-9]+).*[A-Za-z0-9]\\.mp4"

上下文

public static void main(String[] args) {
    String input = "Star Wars Rebels s02e18 - The Forgotten Droid.mp4";

    // From the input the following is matched: 'Star Wars Rebels s02e18 - The Forgotten Droid.mp4'
    String regex = "^[A-Za-z0-9]+\\s.+?s(?<season>[A-Za-z0-9]+)e(?<episode>[A-Za-z0-9]+).*[A-Za-z0-9]\\.mp4";
    // MULTILINE due to Boundary matcher '^'
    Matcher matcher = Pattern.compile(regex, Pattern.MULTILINE).matcher(input);

    // The condition have to be true before using "matcher.group()",
    // or 'java.lang.IllegalStateException: No match found' will be thrown.
    if(matcher.find()) {
        // Output: 'Season value:  02'
        System.out.println("Season value:\t" + matcher.group("season"));
        // Output: 'Episode value: 18'
        System.out.println("Episode value:\t" + matcher.group("episode"));
    }
}

有很多方法可以匹配输入以提取季节和剧集。 以下是 Java 的“类模式”列表以获取更多选项:

https://docs.oracle.com/javase/10/docs/api/java/util/regex/Pattern.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 2019-03-08
    相关资源
    最近更新 更多