在双括号占位符之前和之后分割字符串

问题描述 投票:0回答:2

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

字符串示例...

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

由于我对正则表达式还很不了解,有人可以看一下并告诉我正则表达式中缺少什么吗?

php regex placeholder
2个回答
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]]
)

沙盒

当我说

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
)

沙盒

我不会假装,这是我对正则表达式知识的边缘,我应该注意这匹配单括号而不是专门的双括号。 您可以尝试类似的方法

/(\[(\[(?:[^\[\]]|(?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 帐户上有一些如何做到这一点的示例。 正则表达式(本身)不适合嵌套元素。 大多数正则表达式解决方案都会在嵌套时失败。


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);
© www.soinside.com 2019 - 2024. All rights reserved.