【问题标题】:Extracting key-value pairs from multiline text in java从java中的多行文本中提取键值对
【发布时间】:2015-02-12 03:33:28
【问题描述】:

考虑以下多行字符串:

This is multiline text that needs to be correctly parsed into key-value pairs, excluding all other information.

 Section One:
    First key = Value One
    Second key = Value Two

 Section Two:   
    Third key = Value Three
    Fourth key = Value Four
    Fifth key = Value Five

 Section Three:
    Sixth key = Value Six
    Seventh key = Value Seven
    Eighth key = Value Eight

换句话说,文本由“介绍”(一些短语)组成,后面是多行,按部分组织,每个部分都有一个“标题”(例如,Section One)和多个键值对,以= 分隔。

键可以包含除换行符和= 之外的任何字符,值可以包含除换行符之外的任何字符。

有时,文本中可能会出现其他不相关的行。

需要一个正则表达式,它会导致matched.find() 返回所有键值对组,并且只返回那些,跳过介绍和节标题,以及任何其他没有键值对的行。

理想情况下,不需要其他文本预处理或后处理。

逐行读取文本并进行相应处理在此用例中不是一个选项。

(?:\r|\n)(\s*[^=\.]+)\s*=\s*(.+) 之类的模式非常接近,但它们仍然包含更多要求。

有什么想法吗?

【问题讨论】:

  • 如果间距不变,也可以试试(?m)(?<=^ {4}).+?(?= *= *(.*))
  • 间距不固定,不起作用。不过谢谢。 :-)
  • 您能否详细说明逐行阅读文本并进行相应处理不是此用例中的选项。 ?

标签: java regex key-value matcher keyvaluepair


【解决方案1】:

你快到了。只需将\s* 更改为<space>*,因为\s 也匹配换行符。

(?:\r|\n) *([^\n=\.]+)(?<=\S) *= *(.+)

如果它包含标签,则将上面的space* 更改为[ \t]*(?&lt;=\S) 肯定的lookbehind 断言匹配必须以非空格字符开头。

DEMO

String s = "This is multiline text that needs to be correctly parsed into key-value pairs, excluding all other information.\n" + 
        "\n" + 
        " Section One:\n" + 
        "    First key = Value One\n" + 
        "    Second key = Value Two\n" + 
        "\n" + 
        " Section Two:   \n" + 
        "    Third key = Value Three\n" + 
        "    Fourth key = Value Four\n" + 
        "    Fifth key = Value Five\n" + 
        "\n" + 
        " Section Three:\n" + 
        "    Sixth key = Value Six\n" + 
        "    Seventh key = Value Seven\n" + 
        "    Eighth key = Value Eight";
Matcher m = Pattern.compile("(?:\\r|\\n)[\\t ]*([^\\n=\\.]+)(?<=\\S)[\\t ]*=[\\t ]*(.+)").matcher(s);
while(m.find())
{
    System.out.println("Key : "+m.group(1) + " => Value : " + m.group(2));
}

输出:

Key : First key => Value : Value One
Key : Second key => Value : Value Two
Key : Third key => Value : Value Three
Key : Fourth key => Value : Value Four
Key : Fifth key => Value : Value Five
Key : Sixth key => Value : Value Six
Key : Seventh key => Value : Value Seven
Key : Eighth key => Value : Value Eight

【讨论】:

  • 或者我们也可以使用 \s* 来包含标签。
  • 这就是为什么我告诉你添加[ \t]*
  • 当然。某些节标题后跟一个制表符存在问题 - 出于某种原因,正则表达式将每个此类标题与该节中的第一个键连接起来。第一个版本更简单,并且与第二个版本产生相同的结果。已经 +1,谢谢。
  • 真的 \s 匹配换行符吗?我的印象是没有。
  • 你是对的。那么 (?:\r|\n) * 可以替换为 \s*。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多