【问题标题】:How to parse column separated key-value text with possible multiline strings如何使用可能的多行字符串解析列分隔的键值文本
【发布时间】:2014-05-25 14:12:23
【问题描述】:

我需要解析以下文本:

First: 1
Second: 2
Multiline: blablablabla
bla2bla2bla2
bla3b and key: value in the middle if strting
Fourth: value

Value 是一个字符串或多行字符串,同时 value 可以包含 "key: blablabla" 子字符串。这样的子字符串应该被忽略(不被解析为单独的键值对)。

请帮助我使用正则表达式或其他算法。

理想的结果是:

$regex = "/SOME REGEX/";
$matches = [];
preg_match_all($regex, $html, $matches);
// $mathes has all key and value parsed pairs, including multilines values

谢谢。

我尝试了简单的正则表达式,但结果不正确,因为我不知道如何处理多行:

$regex = "/(.+?): (.+?)/";
$regex = "/(.+?):(.+?)\n/";
...

【问题讨论】:

  • 你应该有精确的模式来分割你的子字符串。在您的场景中,您没有任何确切的模式。

标签: php regex parsing preg-match-all


【解决方案1】:

你可以用这个模式来做:

$pattern = '~(?<key>[^:\s]+): (?<value>(?>[^\n]*\R)*?[^\n]*)(?=\R\S+:|$)~';

preg_match_all($pattern, $txt, $matches, PREG_SET_ORDER);

print_r($matches);

【讨论】:

  • 第5行:前面有多个单词! => regex101.com/r/sR4uA5
  • @Enissay:是的,我知道,这不是 OP 想要的吗?
  • 哦,也许你是对的,我没有理解/读好这个问题......但出于好奇,如果应该考虑到第 5 行,解决方案是什么?
  • @Enissay:以key 为键:(?&lt;key&gt;[^:\s]+):\h(?&lt;value&gt;(?&gt;[^\n]*\R)*?[^\n:]*)(?=\R\S+[ :]|$)
  • @Enissay: 或者更好的(?&lt;key&gt;[^:\v]+):\h(?&lt;value&gt;(?&gt;[^\n:]*\R)*[^\n:]*)(?=\R|$)
【解决方案2】:

你可以这样做,只要你认为一个单词后跟一个冒号在一行的开头是一个新的关键开始:

$data = 'First: 1
Second: 2
Multiline: blablablabla
bla2bla2bla2
bla3b and key: value in the middle if strting
Fourth: value';

preg_match_all('/^([a-z]+): (.*?)(?=(^[a-z]+:|\z))/ims', $data, $matches);

var_dump($matches);

这给出了以下结果:

array(4) {
  [0]=>
  array(4) {
    [0]=>
    string(10) "First: 1
"
    [1]=>
    string(11) "Second: 2
"
    [2]=>
    string(86) "Multiline: blablablabla
bla2bla2bla2
bla3b and key: value in the middle if strting
"
    [3]=>
    string(13) "Fourth: value"
  }
  [1]=>
  array(4) {
    [0]=>
    string(5) "First"
    [1]=>
    string(6) "Second"
    [2]=>
    string(9) "Multiline"
    [3]=>
    string(6) "Fourth"
  }
  [2]=>
  array(4) {
    [0]=>
    string(3) "1
"
    [1]=>
    string(3) "2
"
    [2]=>
    string(75) "blablablabla
bla2bla2bla2
bla3b and key: value in the middle if strting
"
    [3]=>
    string(5) "value"
  }
  [3]=>
  array(4) {
    [0]=>
    string(7) "Second:"
    [1]=>
    string(10) "Multiline:"
    [2]=>
    string(7) "Fourth:"
    [3]=>
    string(0) ""
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-31
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    相关资源
    最近更新 更多