【问题标题】:Match INI Section Blocks匹配 INI 部分块
【发布时间】:2023-03-22 09:41:02
【问题描述】:

我正在使用正则表达式来尝试匹配 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 调试器将它们显示为).)

我在这里做错了什么?

【问题讨论】:

  • 我认为问题出在 Pattern.MULTILINE -- 因为你使用的是贪婪的量词,所以正则表达式会尝试尽可能多地匹配,即文件的全部内容
  • 如果我不使用 Pattern.MULTILINE,我仍然会得到整个文件。

标签: java regex ini


【解决方案1】:

试试这个正则表达式:

(?ms)^\[[^]\r\n]+](?:(?!^\[[^]\r\n]+]).)*

或 Java 字符串文字正则表达式:

"(?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,如果你没有, 然后匹配任何字符。

【讨论】:

    【解决方案2】:

    您使用贪婪量词* 匹配最长的可能字符串。使用不情愿的量词*? 来获得最短的匹配。

    【讨论】:

    • 你的意思是这样吗?: "^\[[^\]\r\n]+](?:\r?\n(?:[^\r\n].* )?)*?”当我使用它时,它只返回“[Section 2]”,而不是整个 Section 2 块。
    猜你喜欢
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2011-11-02
    • 2015-04-07
    相关资源
    最近更新 更多