4

我尝试在Windows下用java解析windows ini文件。假设内容是:

[section1]
key1=value1
key2=value2
[section2]
key1=value1
key2=value2
[section3]
key1=value1
key2=value2

我使用以下代码:

Pattern pattSections = Pattern.compile("^\\[([a-zA-Z_0-9\\s]+)\\]$([^\\[]*)", Pattern.DOTALL + Pattern.MULTILINE);
Pattern pattPairs = Pattern.compile("^([a-zA-Z_0-9]+)\\s*=\\s*([^$]*)$", Pattern.DOTALL + Pattern.MULTILINE);
// parse sections
Matcher matchSections = pattSections.matcher(content);
while (matchSections.find()) {
    String keySection = matchSections.group(1);
    String valSection = matchSections.group(2);
    // parse section content
    Matcher matchPairs = pattPairs.matcher(valSection);
    while (matchPairs.find()) {
        String keyPair = matchPairs.group(1);
        String valPair = matchPairs.group(2);
    }
}

但它不能正常工作:

  1. 第 1 节不匹配。这可能是因为这不是从“EOL 之后”开始的。当我在 then 之前放置空字符串时,[section1]它匹配。

  2. valSection返回 '​​\r\nke1=value1\r\nkey2=value2\r\n' 。keyPair返回'key1' 。看起来还可以。但valPair返回 'value1\r\nkey2=value2\r\n' 但不是根据需要返回 'value1'。

这里有什么问题?

4

2 回答 2

1

您不需要DOTALL标志,因为您的模式中根本不使用点。

我认为 Java 将\n自己视为换行符,因此\r不会被处理。你的模式:

^\\[([a-zA-Z_0-9\\s]+)\\]$

不会是真的,但确实存在

^\\[([a-zA-Z_0-9\\s]+)\\]\r$

将要。

我建议您也忽略 MULTILINE 并使用以下模式作为行分隔符:

(^|\r\n)
($|\r\n)
于 2012-08-09T21:50:23.597 回答
0

第一个正则表达式刚刚起作用(这不是您如何读取文件的问题吗?),第二个正则表达式添加了“?” 签名以不情愿的方式使用它。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

    public static void main(String[] args) {
        String content = "[section1]\r\n" +
        "key1=value1\r\n" +
        "key2=value2\r\n" +
        "[section2]\r\n" +
        "key1=value1\r\n" +
        "key2=value2\r\n" +
        "[section3]\r\n" +
        "key1=value1\r\n" +
        "key2=value2\r\n";

        Pattern pattSections = Pattern.compile(
                "^\\[([a-zA-Z_0-9\\s]+)\\]$([^\\[]*)", Pattern.DOTALL
                        + Pattern.MULTILINE);
        Pattern pattPairs = Pattern.compile(
                "^([a-zA-Z_0-9]+)\\s*=\\s*([^$]*?)$", Pattern.DOTALL
                        + Pattern.MULTILINE);
        // parse sections
        Matcher matchSections = pattSections.matcher(content);
        while (matchSections.find()) {
            String keySection = matchSections.group(1);
            String valSection = matchSections.group(2);
            // parse section content
            Matcher matchPairs = pattPairs.matcher(valSection);
            while (matchPairs.find()) {
                String keyPair = matchPairs.group(1);
                String valPair = matchPairs.group(2);
            }
        }

    }

}
于 2012-05-11T13:51:04.350 回答