在关键字将文本转换为数组

时间:2016-08-05 20:19:57

标签: php arrays regex

我正在尝试将一个文本块添加到PHP中的数组中,将文本分为关键词,在本例中为选项 n ,其中 n 是任何字符或数字。这是一个示例文本:

示例输入

OPTION A: Lorem ipsum dolar sit
Ut mattis velit nec tortor congue gravida. Duis leo arcu, maximus vel convallis vitae, laoreet in metus. Duis nec nisl id eros tincidunt dignissim. Sed condimentum commodo mi, a tristique risus vehicula ut. Sed eget ultrices lacus. Curabitur sed eleifend sapien, nec pharetra nunc.
Note: This option requires Option K-1: Extended Drill Depth. Nunc eu est bibendum nibh ullamcorper fermentum eget ut ante. Cras sed eros ac odio congue auctor. Nunc vel euismod neque.

OPTION D: Quisque efficitur
Morbi elementum metus posuere congue scelerisque. Vestibulum blandit pulvinar leo sit amet ornare. Maecenas porttitor lectus augue, et scelerisque nisl imperdiet non. Curabitur vel ligula sit amet leo auctor malesuada. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin facilisis erat ipsum, ut sagittis velit aliquam a. Nulla nulla orci, dapibus at ullamcorper suscipit, aliquam vel nisl. Duis eu libero ut leo ornare tempor. Donec egestas ipsum nec augue pellentesque aliquet.

OPTION G: Duis leo arcu
Aenean porttitor nulla eu eleifend hendrerit. Duis sed pretium nunc, sed semper leo. Nam sit amet quam semper, tempor risus vitae, consequat ex. Quisque ut rutrum enim, aliquet sodales justo. Morbi fringilla ac justo vitae molestie. Donec in molestie mauris, a scelerisque dolor.
Note: Nunc eu est bibendum nibh ullamcorper fermentum eget ut ante. Cras sed eros ac odio congue auctor. Nunc vel euismod neque.

OPTION IL: Fusce fermentum
Donec sed sagittis purus. Aliquam auctor nibh a varius sagittis. Nullam eget nulla orci. Nam eu dolor posuere, semper dui vitae, mattis leo. Vestibulum vitae dolor fringilla, gravida nulla ac, malesuada urna.

OPTION O: Morbi elementum
Nunc mi nisi, tempus non finibus nec, vulputate quis augue. Sed bibendum, dui nec venenatis efficitur, turpis libero efficitur odio, ac mollis est ex ut arcu. Aenean congue a metus quis euismod. Etiam at dui urna. Duis elementum, sapien ac volutpat mollis, augue neque pellentesque arcu, at finibus ligula nulla et libero. Curabitur vel mauris tortor. Mauris suscipit neque ac mauris lacinia tristique. Quisque faucibus semper lectus, eu ultricies sapien ultrices nec.

所需的输出

理想情况下,我希望上面的示例看起来像这样:

array:15 [▼
  0 => "OPTION A: Lorem ipsum dolar sit
        \n
        Ut mattis velit nec tortor congue gravida. Duis leo arcu, maximus vel convallis vitae, laoreet in metus. Duis nec nisl id eros tincidunt dignissim. Sed condimentum commodo mi, a ristique risus vehicula ut. Sed eget ultrices lacus. Curabitur sed eleifend sapien, nec pharetra nunc. \r\n
        Note: Nunc eu est bibendum nibh ullamcorper fermentum eget ut ante. Cras sed eros ac odio congue auctor. Nunc vel euismod neque."
  1 => "OPTION D: Quisque efficitur
        \n
        Morbi elementum metus posuere congue scelerisque. Vestibulum blandit pulvinar leo sit amet ornare. Maecenas porttitor lectus augue, et scelerisque nisl imperdiet non. Curabitur vel ligula sit amet leo auctor malesuada. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin facilisis erat ipsum, ut sagittis velit aliquam a. Nulla nulla orci, dapibus at ullamcorper suscipit, aliquam vel nisl. Duis eu libero ut leo ornare tempor. Donec egestas ipsum nec augue pellentesque aliquet."
  2 => "OPTION G: Duis leo arcu
        \n
        Aenean porttitor nulla eu eleifend hendrerit. Duis sed pretium nunc, sed semper leo. Nam sit amet quam semper, tempor risus vitae, consequat ex. Quisque ut rutrum enim, aliquet sodales justo. Morbi fringilla ac justo vitae molestie. Donec in molestie mauris, a scelerisque dolor. \r\n
        Note: Nunc eu est bibendum nibh ullamcorper fermentum eget ut ante. Cras sed eros ac odio congue auctor. Nunc vel euismod neque."

  3 = > ...
  4 => ...
  etc.
]

或者使用选项 n 文本作为数组键,作为值的描述也会很优雅,但我不知道如何完成此操作。

使用preg_split()

我一直试图使用preg_split()但收效甚微,我目前的进展如下:

preg_split('/(Option [\w]+: \s*([^\r\n]*))/', $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

哪个输出:

array:15 [▼
  0 => "OPTION A: Lorem ipsum dolar sit"
  1 => "Lorem ipsum dolar sit"
  2 => """
    \r\n
    Ut mattis velit nec tortor congue gravida. Duis leo arcu, maximus vel convallis vitae, laoreet in metus. Duis nec nisl id eros tincidunt dignissim. Sed condimentum commodo mi, a ristique risus vehicula ut. Sed eget ultrices lacus. Curabitur sed eleifend sapien, nec pharetra nunc. \r\n
    Note: Nunc eu est bibendum nibh ullamcorper fermentum eget ut ante. Cras sed eros ac odio congue auctor. Nunc vel euismod neque.\r\n
    """
  3 => "OPTION D: Quisque efficitur"
  4 => "Quisque efficitur"
  5 => """
    \r\n
    Morbi elementum metus posuere congue scelerisque. Vestibulum blandit pulvinar leo sit amet ornare. Maecenas porttitor lectus augue, et scelerisque nisl imperdiet non. Curabitur vel ligula sit amet leo auctor malesuada. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin facilisis erat ipsum, ut sagittis velit aliquam a. Nulla nulla orci, dapibus at ullamcorper suscipit, aliquam vel nisl. Duis eu libero ut leo ornare tempor. Donec egestas ipsum nec augue pellentesque aliquet.\r\n
    """
  6 => "OPTION G: Duis leo arcu"
  7 => "Duis leo arcu"
  8 => """
    \r\n
    Aenean porttitor nulla eu eleifend hendrerit. Duis sed pretium nunc, sed semper leo. Nam sit amet quam semper, tempor risus vitae, consequat ex. Quisque ut rutrum enim, aliquet sodales justo. Morbi fringilla ac justo vitae molestie. Donec in molestie mauris, a scelerisque dolor. \r\n
    Note: Nunc eu est bibendum nibh ullamcorper fermentum eget ut ante. Cras sed eros ac odio congue auctor. Nunc vel euismod neque.\r\n
    """
  9 => "OPTION IL: Fusce fermentum"
  10 => "Fusce fermentum"
  11 => """
    \r\n
    Donec sed sagittis purus. Aliquam auctor nibh a varius sagittis. Nullam eget nulla orci. Nam eu dolor posuere, semper dui vitae, mattis leo. Vestibulum vitae dolor fringilla, gravida nulla ac, malesuada urna.\r\n
    """
  12 => "OPTION O: Morbi elementum"
  13 => "Morbi elementum"
  14 => """
    \r\n
    Nunc mi nisi, tempus non finibus nec, vulputate quis augue. Sed bibendum, dui nec venenatis efficitur, turpis libero efficitur odio, ac mollis est ex ut arcu. Aenean congue a metus quis euismod. Etiam at dui urna. Duis elementum, sapien ac volutpat mollis, augue neque pellentesque arcu, at finibus ligula nulla et libero. Curabitur vel mauris tortor. Mauris suscipit neque ac mauris lacinia tristique. Quisque faucibus semper lectus, eu ultricies sapien ultrices nec.
    """
]

正如您所看到的那样,它会立即复制关键字后面的行,并将描述文本拆分为自己的条目。

我的问题是:是否有更好/更可靠的方法可以在preg_split()之外完成此操作,例如substr与其他方法结合使用?如果不是,我如何修复我的逻辑以实现我的目标?

使用工作解决方案进行更新

感谢@RomanPerekhrest我使用以下代码生成所需的数组:preg_match_all("/\n?OPTION [\w:]+:.+?(?=\nOPTION\s|$)/s", $input, $outputArray);

如果在描述正文中引用了一个选项,它会从该点删除该行的其余部分。解决方案是改变正则表达式:

"/OPTION [^:]+:.+?(?=\n?OPTION\s|$)/s"

对此:

"/\n?OPTION [\w:]+:.+?(?=\nOPTION\s|$)/s"

我仍然是正则表达式的新手,但是如果我理解正确,在新行约束之后删除?会使新行成为需求而非可选,因此选项只会被放入数组中如果他们在新线上,或者是第一线,则作为新密钥。

5 个答案:

答案 0 :(得分:2)

使用preg_match_all函数的解决方案:

// $text is your input text
preg_match_all("/OPTION [^:]+:.+?(?=\n?OPTION\s|$)/s", $text, $matches);
print_r($matches[0]);  // now $matches[0] contains the array of needed items

/s修饰符。 如果设置了此修饰符,则模式中的点元字符将匹配所有字符,包括换行符

(?=...) - 积极的先行断言。匹配当前OPTION内容,如果它后面是下一个OPTION,或者它是列表中的最后一个OPTION(\n?OPTION\s|$

DEMO link

答案 1 :(得分:1)

如何使用前瞻断言(正如@Casimir所指出的那样):

array_filter(preg_split('~(?m)(?=^OPTION)~', $input), 'trim');

答案 2 :(得分:0)

它在每次捕获时都会分裂,甚至是嵌套的捕获。因此([^\r\n]*)将在结果数组中创建单独的元素。根据您的示例数据,您可以简单地拆分两个或多个换行符,以在每个数组元素中包含整个文本块:

preg_split('/[\r\n]{2,}/', $input);

或者,如果您想依赖OPTION字符串,请抓取整个文本块,然后在以下内容之后修剪新行:

$result = preg_split('/(OPTION [\w]+:.*)/', $input, -1, PREG_SPLIT_DELIM_CAPTURE);
// Remove trailing newlines
$result = array_map('trim', $result);

答案 3 :(得分:0)

对我而言,就像你可以使用爆炸分裂空白行。尝试这样的事情:

$pieces = explode("\n\n", $input);

以下是一个示例:https://repl.it/CkBl/0

答案 4 :(得分:0)

看起来你想在换行符上拆分字符串。

explode("\n", $string);