我正在使用正则表达式来尝试匹配INI文件中的节块。我正在使用书中Regular Expressions Cookbook给出的配方,但它似乎对我不起作用。
以下是我正在使用的代码:
final BufferedReader in = new BufferedReader(
new FileReader(file));
String s;
String s2 = "";
while((s = in.readLine())!= null)
s2 += s + System.getProperty("line.separator");
in.close();
final String regex = "^\\[[^\\]\r\n]+](?:\r?\n(?:[^\r\n].*)?)*";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
String sectionBlock = null;
final Matcher regexMatcher = pattern.matcher(s2);
if (regexMatcher.find()) {
sectionBlock = regexMatcher.group();
}
以下是我输入文件的内容:
[Section 2]
Key 2.0=Value 2.0
Key 2.2=Value 2.2
Key 2.1=Value 2.1
[Section 1]
Key 1.1=Value 1.1
Key 1.0=Value 1.0
Key 1.2=Value 1.2
[Section 0]
Key 0.1=Value 0.1
Key 0.2=Value 0.2
Key 0.0=Value 0.0
问题是sectionBlock
最终等于文件的整个内容,而不仅仅是第一部分。
(我不知道这是否重要,但我在Windows上这样做,s2
中的行分隔符等于“\ r \ n”(至少,这是IDEA调试器显示的内容)他们as)。)
我在这里做错了什么?
答案 0 :(得分:5)
请尝试使用此正则表达式:
(?ms)^\[[^]\r\n]+](?:(?!^\[[^]\r\n]+]).)*
或Java String literal regex:
"(?ms)^\\[[^]\r\n]+](?:(?!^\\[[^]\r\n]+]).)*"
(简短)解释:
(?ms) // enable multi-line and dot-all matching
^ // the start of a line
\[ // match a '['
[^]\r\n]+ // match any character except '[', '\r' and '\n', one or more times
] // match a ']'
(?: // open non-capturing group 1
(?! // start negative look-ahead
^ // the start of a line
\[ // match a '['
[^]\r\n]+ // match any character except '[', '\r' and '\n', one or more times
] // match a ']'
) // stop negative look-ahead
. // any character (including line terminators)
)* // close non-capturing group 1 and match it zero or more times
用简单的英语写成:
匹配'['后跟一个或多个 字符除了'[','\ r'和'\ n', 然后是']'(让我们称之为 匹配X)。然后为每个空字符串 在文中,首先展望未来 你没有看到匹配X,如果你没有, 然后匹配任何角色。
答案 1 :(得分:0)
您使用与最长字符串匹配的贪婪量词*
。使用不情愿的量词*?
来获得最短的匹配。