使用java解析文件“/etc/default”

使用java解析文件“/etc/default”,java,regex,parsing,properties,Java,Regex,Parsing,Properties,我试图使用java和正则表达式解析通常在/etc/default中找到的配置文件。到目前为止,这是我在每个文件的每一行上迭代的代码: // remove comments from the line int hash = line.indexOf("#"); if (hash >= 0) { line = line.substring(0, hash); } // create the patterns Pattern doubleQuotePattern = Pattern.c

我试图使用java和正则表达式解析通常在/etc/default中找到的配置文件。到目前为止,这是我在每个文件的每一行上迭代的代码:

// remove comments from the line
int hash = line.indexOf("#");
if (hash >= 0) {
    line = line.substring(0, hash);
}

// create the patterns
Pattern doubleQuotePattern = Pattern.compile("\\s*([a-zA-Z_][a-zA-Z_0-9]*)\\s*=\\s*\"(.*)\"\\s*");
Pattern singleQuotePattern = Pattern.compile("\\s*([a-zA-Z_][a-zA-Z_0-9]*)\\s*=\\s*\\'(.*)\\'\\s*");
Pattern noQuotePattern = Pattern.compile("\\s*([a-zA-Z_][a-zA-Z_0-9]*)\\s*=(.*)");

// try to match each of the patterns to the line
Matcher matcher = doubleQuotePattern.matcher(line);
if (matcher.matches()) {
    System.out.println(matcher.group(1) + " == " + matcher.group(2));
} else {
    matcher = singleQuotePattern.matcher(line);
    if (matcher.matches()) {
        System.out.println(matcher.group(1) + " == " + matcher.group(2));
    } else {
        matcher = noQuotePattern.matcher(line);
        if (matcher.matches()) {
            System.out.println(matcher.group(1) + " == " + matcher.group(2));
        }
    }
}
这正如我所期望的那样有效,但我非常确定,通过使用更好的正则表达式,我可以使这个方法变得更小,但我没有任何运气。有谁知道读取这些类型文件的更好方法吗?

您可以使用它生成解析器。基本上,您可以为要使用的语言编写语法,或者使用其中一种语言,antlr将为您生成解析器。

您可以使用它生成解析器。基本上,您可以为要使用的语言编写语法或使用其中一种语言,antlr将为您生成解析器。

在许多情况下,您可以使用java.util.Properties来处理shell配置文件

实际上,如果您不使这些文件过于复杂,您可以通过这种方式在shell脚本和java程序之间共享它们

不能很好地处理的是带引号的字符串。

在许多情况下,您可以使用java.util.Properties来处理shell配置文件

实际上,如果您不使这些文件过于复杂,您可以通过这种方式在shell脚本和java程序之间共享它们


不能很好地处理的是带引号的字符串。

这里有一种模式可以使用,与上面的三种模式相同:

Pattern etcPattern = Pattern.compile(
   "\\s*([a-zA-Z_]\\w*)\\s*=\\s*"+
   "(\"|'|.{0,0})(.*?)\\2"+  //QUOTE MATCHING
   "\\s*");
这和您的有三个区别:首先,我将表达式[a-zA-Z0-9_]替换为预定义的字符类\w一个单词字符。第二部分引号匹配是一种模式,它将匹配和剥离外部平衡引号,但也允许不平衡引号,就像三种模式一样

它首先使用模式\|'|.{0,0}。这是

双引号 一句话 任何零次 然后是您的.*模式,后跟一个反向引用\2。backreference表示要匹配模式2所匹配的内容和报价模式。这就是上面第三种情况的重要性所在。如果该值不是以单引号或双引号开头,则需要能够忽略它。因此,它首先尝试匹配其中一个引号。如果不能,那么它将匹配空字符串,这反过来允许反向引用匹配空字符串

要使其工作,最后一个改变是将内部。*模式更改为不愿意。*?因此,如果可能的话,它将允许引用与反向引用匹配,并将其剥离

因此,您应该能够以以下方式运行:

Matcher matcher = etcPattern.matcher(line);
if (matcher.matches()) {
    System.out.println(matcher.group(1) + " == " + matcher.group(3));
}

与上面的示例相同,请注意,该值现在位于匹配组3中,而不是两个。正如我所说的,这与您的模式相匹配,特别是它将允许不平衡的引号,并允许对值进行任何内部引号。

这里有一个您可以使用的模式,相当于上述三个模式:

Pattern etcPattern = Pattern.compile(
   "\\s*([a-zA-Z_]\\w*)\\s*=\\s*"+
   "(\"|'|.{0,0})(.*?)\\2"+  //QUOTE MATCHING
   "\\s*");
这和您的有三个区别:首先,我将表达式[a-zA-Z0-9_]替换为预定义的字符类\w一个单词字符。第二部分引号匹配是一种模式,它将匹配和剥离外部平衡引号,但也允许不平衡引号,就像三种模式一样

它首先使用模式\|'|.{0,0}。这是

双引号 一句话 任何零次 然后是您的.*模式,后跟一个反向引用\2。backreference表示要匹配模式2所匹配的内容和报价模式。这就是上面第三种情况的重要性所在。如果该值不是以单引号或双引号开头,则需要能够忽略它。因此,它首先尝试匹配其中一个引号。如果不能,那么它将匹配空字符串,这反过来允许反向引用匹配空字符串

要使其工作,最后一个改变是将内部。*模式更改为不愿意。*?因此,如果可能的话,它将允许引用与反向引用匹配,并将其剥离

因此,您应该能够以以下方式运行:

Matcher matcher = etcPattern.matcher(line);
if (matcher.matches()) {
    System.out.println(matcher.group(1) + " == " + matcher.group(3));
}

与上面的示例相同,请注意,该值现在位于匹配组3中,而不是两个。正如我所说,这与您的模式相匹配,特别是它将允许不平衡的引号,并允许对值进行任何内部引号。

我认为一个简单的正则表达式就足够了。我一直无法使用X | Y | Z构造并将双引号或单引号分条,我认为一个简单的正则表达式就足够了。我无法使用X | Y | Z构造并对双引号或单引号进行条带化,带引号的字符串正是我遇到的问题。我可能会使用属性文件,然后检查值并删除引号,但这似乎有点不对劲……引号中的字符串正是我遇到的问题。我可能会使用属性文件,然后检查值并删除引号,但这似乎有点骇人…太好了。。。它工作得很好。这就是我如此喜欢的原因。伟大的皮奥
请写伟大的代码。很高兴这是你正在寻找的,快速注意模式允许不平衡的引用,我最初有一个打字错误说它没有,我已经修复了。伟大的。。。它工作得很好。这就是我如此喜欢的原因。伟大的人写伟大的代码。很高兴这是你所寻找的,快速注意模式允许不平衡的引用我最初有一个打字错误说它没有,我已经修复了。