将文本转换为关键字处的数组


Convert text to array at key word

我正试图在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);

有一个问题是,如果在描述的正文中引用了一个选项,它会从那一点删除行的其余部分。解决方案是从以下内容更改regexp:

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

对此:

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

我对regex还很陌生,但如果我正确理解,在新行约束后删除?会使新行成为一个要求,而不是可选的,因此,只有当选项在新行上或是第一行时,它们才会作为新键放入数组中。

使用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

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

(?=...)-正向前瞻断言。如果后面跟下一个OPTION或是列表('n?OPTION's|$(中的最后一个OPTIION,则匹配当前OPTION内容

DEMO链接

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

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

在我看来,您可以使用爆炸来拆分空行。试试这样的东西:

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

以下是一个示例:https://repl.it/CkBl/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);

看起来您想在换行时拆分字符串。

explode("'n", $string);