【问题标题】:Regex to partition multiline string正则表达式对多行字符串进行分区
【发布时间】:2015-05-03 10:21:44
【问题描述】:

考虑一个由N lines 组成的多行字符串,如下所示:

Line 1 text
Line 2 text
Line 3 text
...
Line n-1 text
Line n text
anchor=value
Line n+2 text
Line n+3 text
Line n+4 text
...
Line N text

anchor 键不会出现在任何行内,并且在锚点之前以及其后的 = 符号周围可能有空格。

我需要一个将上述字符串分成 3 组的正则表达式:

  1. 第 1 行至第 n 行(含)
  2. 锚线(分割点)
  3. 第 n+2 行至第 N 行(含)

我最接近解决方案的是

(?s)^(?:(?!anchor\s*=\s*).)+?\r|\nanchor\s*=\s*([^\r\n]+)(?:\r|\n)(.*)

但上述正则表达式将整个文本包含在第一个匹配组中,并按预期填充剩余的 2 个组。

另一个要求是正则表达式必须尽可能快,因为它将应用于大量数据。另请注意,在此用例中,通过单个正则表达式进行处理是唯一的选择。

有什么想法吗?

【问题讨论】:

    标签: java regex multiline multilinestring


    【解决方案1】:

    这个正则表达式呢?

    (?s)^(.*?)(anchor\s*\=\s*[^\r\n]+)(.*?)

    或者,匹配字符串的结尾,

    (?s)^(.*?)(anchor\s*\=\s*[^\r\n]+)(.*?)$?

    【讨论】:

    • 如果最后一组中的非贪婪运算符变得贪婪,则第一个有效。秒按原样工作。谢谢!
    • @PNS,不客气。我知道(.*?) 模式可能需要一些边界才能命中,所以我添加了第二个选项。
    • 是的,他们似乎很好。谢谢。
    【解决方案2】:

    嗯,你可以先拿到锚,然后在上面拆分:

    String anchor = str.replaceAll("(?ms).*?(anchor\\s*=.*?)$.*", "$1");
    String lineParts = str.split("\\Q" + anchor + "\\E");
    

    “m”标志使 ^ 和 $ 匹配行的开始/结束。

    【讨论】:

    • 谢谢,但这里需要一个单一的正则表达式来完成这一切,因为代码不允许其他任何事情。无论如何+1。 :-)
    【解决方案3】:

    如果您需要速度巨大的字符串,而正则表达式不是您的选择。您必须将整个字符串保存在内存中才能使用正则表达式对其进行标记。我建议改用 Reader / InputStreams。

    【讨论】:

    • 当然,但在这个用例中,输出来自一个只允许通过正则表达式进行自定义的库。
    • 现在我更加困惑了。如果输出来自库,为什么要进行拆分?您的意思是字符串是由库返回的吗?
    • 它由允许“注入”正则表达式的库处理。
    • @PNS“仅允许通过正则表达式进行自定义的库”此信息应放在您的问题中。还要描述这个正则表达式将如何被你的库应用:它是 split 的参数还是 find() 的参数?
    • 没有拆分,它适用于示例中的文本块,因此我们可能正在寻找matches()。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 2013-06-12
    相关资源
    最近更新 更多