我正在尝试使用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));
}
}
}
这可以按照我的预期运作,但我很确定我可以通过使用更好的正则表达式来减小这种方式,但我没有运气。有人知道更好的方法来阅读这些类型的文件吗?
答案 0 :(得分:2)
您可以使用antlr生成解析器。基本上你为你想要使用的语言编写语法(或者使用众多grammars already written中的一个语法,而antlr将为你生成一个解析器。
答案 1 :(得分:1)
在许多情况下,您可以使用java.util.Properties
来处理shell配置文件。
实际上,如果你不使这些文件过于复杂,你可以在shell脚本和java程序之间以这种方式共享它们。
不能很好地处理的事情是引用的字符串。
答案 2 :(得分:1)
以下是您可以使用的单个模式,相当于上面的三个模式:
Pattern etcPattern = Pattern.compile(
"\\s*([a-zA-Z_]\\w*)\\s*=\\s*"+
"(\"|'|.{0,0})(.*?)\\2"+ //QUOTE MATCHING
"\\s*");
这和你之间有三个不同之处:首先我将表达式[a-zA-Z0-9_]替换为其预定义的字符类\ w(单词字符)。第二部分(QUOTE MATCHING)是一种匹配和剥离外部平衡报价的模式,但也允许三种模式的不平衡报价。
首先使用模式(\“|'|。{0,0})。这是
然后你的。*模式后跟反向引用\ 2。反向引用表示匹配模式2(引用模式)匹配的内容。这是上述第三种情况很重要的地方。如果值不以单引号或双引号开头,则需要能够忽略它。所以它首先尝试匹配其中一个引号。如果它不能那么它将匹配空字符串,这反过来允许反向引用匹配空字符串。
使其工作的最后一项更改是将内部。*模式更改为不情愿(至。*?),以便在可能的情况下允许引号与后引用匹配并被剥离。
所以你应该可以这样运行:
Matcher matcher = etcPattern.matcher(line);
if (matcher.matches()) {
System.out.println(matcher.group(1) + " == " + matcher.group(3));
}
等同于上面的示例(请注意,值现在位于匹配组3中而不是两个。正如我所说,这与您的模式相匹配,特别是它将允许不平衡的引号,并允许任何内部引用该值。