PHP preg_split将分隔符保留在其他元素中

时间:2018-10-19 05:17:17

标签: php regex

我正在尝试将字符串拆分成多个部分。

字符串示例...

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]]"

由于我对Regex的理解还很遥远,所以有人可以看看并告诉我regex中缺少什么吗?

2 个答案:

答案 0 :(得分:3)

这将使您非常接近

 $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]]
)

Sandbox

当我说pretty close时,我的意思确实非常接近...

正则表达式非常简单,捕获2 [,然后捕获],然后捕获]中的2。这就是我们的定界符,然后我们将其捕获。没有空标记也很好。

享受!

更新

  

但在“这是我的表[[{{widget]:“ table”,“ id”:“ 1”,“ title”:“ Views Table”,“ columns”:[]}]上失败,并且这是更多文字” ...注意“列”下的“ []”

要处理此问题,您将需要使用(?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
)

Sandbox

我不会假装,这在我对正则表达式的了解中是一种优势,我应该注意,它与单括号而不是双括号匹配。您可以尝试类似/(\[(\[(?:[^\[\]]|(?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帐户上执行此操作的示例。正则表达式(本身)不适用于嵌套元素。大多数正则表达式解决方案都会在嵌套时失败。

答案 1 :(得分:0)

您可能考虑改用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);