【问题标题】:What is the best way to explode a string with simple markup into an array?将带有简单标记的字符串分解为数组的最佳方法是什么?
【发布时间】:2016-07-19 13:00:25
【问题描述】:

在 PHP 中,我想找出最好的方法来获取包含一些简单标签的字符串,并将其分解为一个多维数组,每个索引包含另外两个数组,其中包含项目 tagstext。如果没有异常标签,tags 将是 null。如果字符串的一部分上存在一个(或多个)标签,tags 将包含所有相关标签指示符的空格分隔列表。

例子:

字符串

The __**quick** brown__ fox jumped __over the__ lazy dog.

处理过的数组

[
    [
        'tags' => null,
        'text' => 'The ',
    ],
    [
        'tags' => '__ **',
        'text' => 'quick',
    ],
    [
        'tags' => '__',
        'text' => ' brown',
    ],
    [
        'tags' => null,
        'text' => ' fox jumped ',
    ],
    [
        'tags' => '__',
        'text' => 'over the',
    ],
    [
        'tags' => null,
        'text' => ' lazy dog.',
    ],
]

我正在努力思考什么是做这件事的最佳方式。这个概念看起来很简单,但我越想它,我就越困惑如何执行它。在foreach 中使用preg_match 函数的某种组合是最好的方法,还是有其他选择?任何指向正确方向的帮助将不胜感激。

【问题讨论】:

  • 您希望得到什么样的结果?你试过explode()吗?
  • 我认为您正在寻找的是一个 tokenizer。想象一下这样的输出:[ [ "text", "The " ], [ "tag", "__" ], [ "tag", "**" ], [ "text", "quick" ], [ "tag", "**" ], [ "text", " brown" ] .. etc(有点浓缩,因为我这里没有太多空间)。我不知道正则表达式是否是这里最好的工具。我认为对字符串进行循环以找到每个 tag 就足够了。每个标记都是 ( text|tag, [value] ) 的元组。

标签: php arrays tags explode


【解决方案1】:

因为您有叠瓦标记,所以您需要一个堆栈来跟踪叠瓦级别。没有办法直接使用正则表达式来做到这一点,因此只对字符串符号进行迭代可能更容易。

作为开始:

print_r(process("The __**quick** brown__ fox jumped __over the__ lazy dog."));

function process($str) {
  $str = '~~'.$str.'~~';
  $sz = strlen($str);

  $res = array();
  $stack = array();
  $text = '';

  for($n = 0; $n < $sz; $n++) {
    if(strpos('*_~', $c = $str[$n]) === false) {
      $text .= $c;
      continue;
    }
    if($text) {
      $res[] = array('text' => $text, 'tags' => implode(" ", array_slice($stack, 1)));
      $text = '';
    }
    $c .= $str[$n++];
    $c == end($stack) ? array_pop($stack) : $stack[] = $c;
  }
  return $res;
}

输出:

Array
(
    [0] => Array
        (
            [text] => The
            [tags] =>
        )
    [1] => Array
        (
            [text] => quick
            [tags] => __ **
        )
    [2] => Array
        (
            [text] =>  brown
            [tags] => __
        )
    [3] => Array
        (
            [text] =>  fox jumped
            [tags] =>
        )
    [4] => Array
        (
            [text] => over the
            [tags] => __
        )
    [5] => Array
        (
            [text] =>  lazy dog.
            [tags] =>
        )
)

一些注意事项:

  • 此代码假定输入正确。它不执行任何检查。
  • 在内部,整个字符串被封装到“~~”标记中。这样,字符串处理以“标签结束”条件结束,最后一个待处理的文本块被正确地附加到结果集中。 (叫我懒狗吧。)但是这个标记并没有注入到最终结果中。

【讨论】:

    【解决方案2】:

    魔鬼并没有画的那么黑。

    $str = 'The __**quick** brown__ fox jumped __over the__ lazy dog.';
    
    $t = array_map(function($i) { 
         $i = preg_split('/[^ A-Za-z]+\K/', $i,2); 
         if (count($i) == 1) array_unshift($i, null);
         return $i;
         },  preg_split('/[A-Za-z.,]\K(?=[^A-Za-z.,])/', $str));   
    print_r($t);
    

    demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      • 1970-01-01
      • 2012-07-17
      • 1970-01-01
      • 2012-01-07
      • 2013-06-23
      • 2021-07-21
      相关资源
      最近更新 更多