Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 7正则表达式和具有多个模式的命名组_Java_Regex_Grouping - Fatal编程技术网

Java 7正则表达式和具有多个模式的命名组

Java 7正则表达式和具有多个模式的命名组,java,regex,grouping,Java,Regex,Grouping,我有两个不同的源向我的应用程序提供输入文件。它们的文件名模式不同,但它们包含我想要检索的公共信息 使用regex命名的组似乎很方便,因为它允许最大程度的代码分解,但是它有其局限性,因为如果两个模式使用相同的组名,我就无法对它们进行区分 例子: 换言之,这: String PATTERN_GROUP_NAME = "name"; String PATTERN_GROUP_DATE = "date"; String PATTERN_IMPORT_1

我有两个不同的源向我的应用程序提供输入文件。它们的文件名模式不同,但它们包含我想要检索的公共信息

使用regex命名的组似乎很方便,因为它允许最大程度的代码分解,但是它有其局限性,因为如果两个模式使用相同的组名,我就无法对它们进行区分

例子: 换言之,这:

String PATTERN_GROUP_NAME   = "name";
String PATTERN_GROUP_DATE   = "date";
String PATTERN_IMPORT_1     = "(?<" + PATTERN_GROUP_NAME + ">[a-z]{3})_(?<" + PATTERN_GROUP_DATE + ">[0-9]{14})_(stuff stuf)\\.xml";
String PATTERN_IMPORT_2     = "(stuff stuf)_(?<" + PATTERN_GROUP_DATE + ">[0-9]{14})_(?<" + PATTERN_GROUP_NAME + ">[a-z]{3})_(other stuff stuf)\\.xml";
Pattern universalPattern    = Pattern.compile(PATTERN_IMPORT_1 + "|" + PATTERN_IMPORT_2);
try {
  DirectoryStream<Path> list = Files.newDirectoryStream(workDirectory);
  for (Path file : list) {
    Matcher matcher = universalPattern.matcher(file.getFileName().toString());
    name = matcher.group(PATTERN_GROUP_NAME);
    fileDate = dateFormatter.parseDateTime(matcher.group(PATTERN_GROUP_DATE));
    (...)
stringpattern\u GROUP\u NAME=“NAME”;
字符串模式\u GROUP\u DATE=“DATE”;
字符串模式\u IMPORT\u 1=“(?[a-z]{3})\u(?[0-9]{14})\u(stuff)\\\.xml”;
字符串模式(stuff stuf)([0-9]{14})([a-z]{3})(其他stuff stuf)\\\.xml);
Pattern universalPattern=Pattern.compile(Pattern_IMPORT_1+“|”+Pattern_IMPORT_2);
试一试{
DirectoryStream list=Files.newDirectoryStream(workDirectory);
用于(路径文件:列表){
Matcher Matcher=universalPattern.Matcher(file.getFileName().toString());
name=matcher.group(模式组名称);
fileDate=dateFormatter.parseDateTime(matcher.group(PATTERN_group_DATE));
(...)
将使用
java.util.regex.PatternSyntaxException
失败,因为已定义了命名的捕获组

解决此问题最有效/最优雅的方法是什么?

编辑:

不用说,但是我可以匹配输入文件的两种模式完全不同,因此没有任何输入文件可以同时匹配这两种模式。

使用两种模式-然后组名就可以相等。

你要求的是高效和优雅。理论上的一种模式可能更有效,但这与这里无关

第一:代码会稍微长一点,但可读性更好——这是正则表达式的一个弱点。这使得它更易于维护

在伪代码中:

Matcher m = firstPattern.matcher ...
if (!m.matches()) {
    m = secondPattern.matcher ...
    if (!m.matches()) {
        continue;
    }
}
name = m.group(NAME_GROUP);
...

(每个人都想做太聪明的编码,但可能需要简单。)

同意Joop Eggen的观点。两种模式简单且易于维护。
只是为了好玩,并为您的具体案例提供一个模式实现

实际上,在您的情况下,“前瞻”是不必要的。因为在一个模式中,您不能分配两个同名的GOUP。因此,通常,您需要修改您的模式。

从AB | BA-->(A | B){2}

我最终还是这么做了。我喜欢写“聪明”的代码,但我想这是其中一个吻最好的例子。+1表示“每个人都想做太聪明的编码,但可能需要简单。”,让我笑了:)@SilverQuettier这是一个如此简单的回答,我不太希望被接受。很高兴遇到专业人士。
String[] inputs = {
        "stuff stuf_20111130121212_abc_other stuff stuf.xml",
        "stuff stuf_20111130151212_def_other stuff stuf.xml",
        "abc_20141220202020_stuff stuf.xml", 
        "def_20140820202020_stuff stuf.xml"
        };    
    String lookAhead = "(?=([a-z]{3}_[0-9]{14}_stuff stuf\\.xml)|(stuff stuf_[0-9]{14}_[a-z]{3}_other stuff stuf\\.xml))";
    String onePattern = lookAhead
            + "((?<name>[a-z]{3})_(other stuff stuf)?|(stuff stuf_)?(?<date>[0-9]{14})_(stuff stuf)?){2}\\.xml";


Pattern universalPattern = Pattern.compile(onePattern);
for (String input : inputs) {
    Matcher matcher = universalPattern.matcher(input);
    if (matcher.find()) {
        //System.out.println(matcher.group());
        String name = matcher.group("name");
        String fileDate = matcher.group("date");
        System.out.println("name : " + name + " fileDate: "
                + fileDate);
    }
}
name : abc fileDate: 20111130121212
name : def fileDate: 20111130151212
name : abc fileDate: 20141220202020
name : def fileDate: 20140820202020