PHP preg_split将分隔符保留在不同的元素中



我正在尝试将字符串拆分为一个部分数组。

字符串示例...

The quick brown fox [[random text here]] and then [[a different text here]]

方括号之间的文本将发生变化,无法提前确定。到目前为止,我拥有的preg_split将拆分,但它将分隔符放置在生成的数组中的其他元素中,而不是我希望它所在的元素中。

$page_widget_split = preg_split('@(?<=[[)(.*?)(?=]])@', $page_content,-1, PREG_SPLIT_DELIM_CAPTURE);

这会产生这样的东西...

[0] => "The quick brown fox [[",
[1] => "random text here]]",
[2] => " and then [[",
[3] => "a different text here]]"

所需的结果如下所示...

[0] => "The quick brown fox",
[1] => "[[random text here]]",
[2] => " and then ",
[3] => "[[a different text here]]"

由于我远未理解正则表达式,有人可以看看并告诉我正则表达式中缺少什么吗?

这会让你非常接近

$page_content = 'the quick brown fox [[random text here]] and then [[a different text here]]';
print_r(preg_split('/([[[^]]+]])/', $page_content, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY));

要记住的是,这是分隔符([[[^]]+]])

输出:

Array
(
[0] => the quick brown fox 
[1] => [[random text here]]
[2] =>  and then 
[3] => [[a different text here]]
)

沙盒

当我说pretty close时,我的意思是真的非常接近......

正则表达式非常简单,捕获 2[然后捕获除]然后 2 个]。 这构成了我们的分隔符,然后我们捕获它。 没有空旗也很好。

享受!

更新

但它在"这是我的表[[{"小部件":"表","id":"1","标题": "视图表", "列": []}]] 上失败,这是更多文本"...请注意"列"下的"[]"

要解决这个问题,您需要使用(?R)的递归正则表达式模式,如下所示:

$page_content = 'here is my table [[{"widget":"table","id":"1","title": "Views Table", "columns": []}]] and this is more text [someother bracket]';
print_r(preg_split('/([(?:[^[]]|(?R))*])/', $page_content, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY));

输出:

Array
(
[0] => here is my table 
[1] => [[{"widget":"table","id":"1","title": "Views Table", "columns": []}]]
[2] =>  and this is more text 
[3] => [someother bracket] //single bracket capture
)

沙盒

我不会假装,这是我对正则表达式知识的边缘,我应该注意这匹配单括号而不是特定的双括号。 您可以尝试这样的事情,/([([(?:[^[]]|(?2))*])])/(?2)就像(?R)但针对特定的捕获组。 这只能匹配[[ ... ]],同时保持内部嵌套。 但问题是,然后你复制了捕获,所以你最终会得到这个:

Array
(
[0] => here is my table 
[1] => [[{"widget":"table","id":"1","title": "Views Table", "columns": []}]]
[2] => [{"widget":"table","id":"1","title": "Views Table", "columns": []}]
[3] =>  and this is more text [someother bracket]
)

请注意它如何不捕获[someother bracket],但它捕获另一个 2 次。 可能有办法解决这个问题,但我想不起来。

宁愿或不捕获单括号对是一个我不知道的问题。

但我以前用过这个,主要用于匹配,匹配的"对或( ),但它是相同的概念。

唯一的其他解决方案是为它制作一个词法分析器/解析器,我在我的 GitHub 帐户上有一些如何做到这一点的例子。 正则表达式(本身(不适合嵌套元素。 大多数正则表达式解决方案在嵌套时都会失败。

你可以考虑使用preg_match_all改用,它可能会使正则表达式的逻辑更容易弄清楚:

/[{2}.+?]{2}|.+?(?=[{2}|$)/

在以下两者之间交替:

  • [{2}.+?]{2}、匹配[[、惰性重复字符,后跟匹配]]

  • .+?(?=[{2}|$),延迟重复字符,直到前瞻匹配[[或字符串的末尾

https://regex101.com/r/ls6oBa/1

在 PHP 中:

$str = "The quick brown fox [[random text here]] and then [[a different text here]] foobar";
preg_match_all('/[{2}.+?]{2}|.+?(?=[{2}|$)/',$str, $result);

相关内容

最新更新