在标签处分割字符串,删除空结果。

3
考虑以下情况。我正在基于{tags}对字符串进行分割,这些大括号中间可以有任意数量的字符(和/或数字):
$string = "Lorem {FOO} ipsum {BAR} dolor {FOO:bar} samet";
$temp   = preg_split('/(\{.*?\})/', $string, -1, PREG_SPLIT_DELIM_CAPTURE);

生成的数组($temp)如下:
Array (
  [0] => Lorem [1] => {FOO} [2] => ipsum [3] => {BAR} 
  [4] => dolor [5] => {FOO:bar} [6] => samet
)

然而,如果$string以标记结尾,例如:
$string = "Lorem {FOO} ipsum {BAR} dolor {FOO:bar}";

然后生成的数组($temp)中包含一个空元素(在这种情况下是#6):

Array (
  [0] => Lorem [1] => {FOO} [2] => ipsum [3] => {BAR} 
  [4] => dolor [5] => {FOO:bar} [6] =>
)

显然,通过检查空值可以删除这些内容,但在我看来,这不是最优雅的方式。是否有另一种方法(例如使用正则表达式),使得结果数组中没有空元素?
2个回答

3

可以使用标志PREG_SPLIT_NO_EMPTY,如下所示:

$string = "Lorem {FOO} ipsum {BAR} dolor {FOO:bar}";
$arr = preg_split('/(\{.*?\})/', $string, 0, 
                  PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
print_r($arr);

输出:

Array
(
    [0] => Lorem 
    [1] => {FOO}
    [2] =>  ipsum 
    [3] => {BAR}
    [4] =>  dolor 
    [5] => {FOO:bar}
)

2

您当前使用的正则表达式/(\{.*?\})/可以进行修改,如果分隔符是字符串的最后一个元素,则不需要拆分。使用/(\{.*?\})(?!$)/,它使用负向先行断言 ((?!…)) 来确保您的模式仅在未跟随 EOL ($) 时匹配。但现在该模式不再被识别,导致模式之前的最后一个元素和模式没有被分开。您将得到以下结果:

array(5) {
    "Lorem "
    "{FOO}"
    " ipsum "
    "{BAR}"
    " dolor {FOO:bar}"
}

显然这也不是你想要的。首先想到的是检查拆分结果的第一个和最后一个元素是否为空。如果是,就将它们移除。可能像这样:

<?php

$string = "{FOO} ipsum {BAR} dolor {FOO:bar}";
$temp   = preg_split('/(\{.*?\})/', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
$i = 0;
if (isset($temp[$i]) && $temp[$i] === '') {
    array_shift($temp);
}
$i = count($temp) -1;
if (isset($temp[$i]) && $temp[$i] === '') {
    array_pop($temp);
}

var_dump($temp);

这个表达式的输出是:Array ([0] => Lorem [1] => {FOO} [2] => ipsum [3] => {BAR} [4] => dolor {FOO:bar}) - 最后一个数组元素包含 "dolor" 和 {FOO:bar}。我想要的是:Array ([0] => Lorem [1] => {FOO} [2] => ipsum [3] => {BAR} [4] => dolor [5] => {FOO:bar}),其中 {FOO:bar} 单独成为最后一个元素。这是你尝试做的吗?还是我没有正确理解你的评论? - Pr0no
1
我不小心提前点击了保存按钮,对此感到抱歉。现在您可以查看完整的答案了... - rodneyrehm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接