我有一个像这样的String变体:

杰夫303 1989年6月
或字符串可以是
杰夫303 1989年6月

我正在使用一个reg来匹配此名称,并希望使用组名,以便我始终知道要提取的数据。我有一个正则表达式,可以确保如果字符串是JEFF 303 1989年6月,则1989和6月可以在第3和第4组中,但是如果字符串是JEFF 303 1989年6月,则将June放在第3组中,将1989放在第4组中。希望避免这种情况,并确保按组名或组号提取它。

到目前为止,我已经编写了代码。

    final String regex ="^(?<name>[a-z]+)[ :-]?(?<id>\\d+)\\s((?<month>[a-z]+)|(?<year>\\d+))?((?<=[a-z] {0,1})\\d+|(?<=\\d {0,1})(?<month>[a-z]+))$";


        final String string = "JEFF 303 JUNE 1989";

        final String string1 = "JEFF 303 1989 JUNE";

        final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        final Matcher matcher = pattern.matcher(string);


        matcher.find();
        String nameGroup = matcher.group("name");
        String id = matcher.group("id");
        String month = matcher.group("month");
        String year = matcher.group("year");

最佳答案

如果您使用命名捕获组,我认为您在交替|的每一侧都不能使用相同的组名。您可以使用2个正则表达式吗?

public static boolean findMatch(String regex, String input) {
  Pattern pattern = Pattern.compile(regex);
  Matcher matcher = pattern.matcher(input);

  if(matcher.find()) {
    String name = matcher.group("name");
    String id = matcher.group("id");
    String month = matcher.group("month");
    String year = matcher.group("year");

    // just print it out, maybe you want to return it instead
    System.out.printf("name: %s, id: %s, month: %s, year: %s", name, id, month, year);
    return true;
  }

  return false;
}

public static void main(String[] args) {
  String input = "JEFF 303 JUNE 1989";
  //String input = "JEFF 303 1989 JUNE";

  // I simplified the regexes
  String regex1 = "(?<name>\w+) (?<id>\d+) (?<month>\w+) (?<year>\d+)";
  String regex2 = "(?<name>\w+) (?<id>\d+) (?<year>\d+) (?<month>\w+)";

  if(findMatch(regex1, input)) {
    // found it with first regex
  } else if(findMatch(regex2, input)) {
    // found it with second regex
  } else {
    // didn't match
  }
}

10-01 14:07