【问题标题】:PHP: How to find text NOT between particular tags?PHP:如何在特定标签之间查找文本?
【发布时间】:2012-09-24 09:52:15
【问题描述】:

示例输入字符串:“[A][B][C]test1[/B][/C][/A] [A][B]test2[/B][/A] test3”

我需要找出文本的哪些部分不在 A、B 和 C 标签之间。因此,例如,在上面的字符串中,它是“test2”和“test3”。 “test2”没有 C 标签,“test3”根本没有任何标签。

If 也可以这样嵌套: 示例输入字符串 2:“[A][B][C]test1[/B][/C][/A] [A][B]test2[C]test4[/C][/B][/A]测试3"

在此示例中添加了“test4”,但“test4”具有 A、B 和 C 标签,因此输出不会改变。

有人知道我该如何解析这个吗?

【问题讨论】:

  • 查看正则表达式
  • @Erik 标签将始终保持相同的顺序[A][B][C][/C][/B][A] 吗?
  • 不,标签可以是任何顺序,结束标签的顺序也可以与开始标签的顺序不同

标签: php parsing text tags


【解决方案1】:

这个解决方案并不干净,但它可以解决问题

$string = "[A][B][C]test1[/B][/C][/A] [A][B]test2[/B][/A] test3" ;
$string = preg_replace('/<A[^>]*>([\s\S]*?)<\/A[^>]*>/', '', strtr($string, array("["=>"<","]"=>">")));
$string = trim($string);
var_dump($string);

输出

 string 'test3' (length=5)

【讨论】:

    【解决方案2】:

    考虑到你们每个人的标签都在[A][/A]中,你可以做的是:分解[/A]并验证每个数组是否包含[A]标签,如下所示:

    $string = "[A][B][C]test1[/B][/C][/A] [A][B]test2[/B][/A] test3";
    
    $found = ''; // this will be equal to test3
    $boom = explode('[/A]', $string);
    
    foreach ($boom as $val) {
     if (strpos($val, '[A] ') !== false) { $found = $val; break; }
    }
    
    echo $found; // test3
    

    【讨论】:

    • 这行不通。不支持嵌套标签,甚至输出错误,因为“test2”不在[C]标签内,所以它也应该被发现......我认为它不能用简单的explode()来完成跨度>
    【解决方案3】:

    试试下面的代码

    $str = 'test0[A]test1[B][C]test2[/B][/C][/A] [A][B]test3[/B][/A] test4';
    $matches  = array();
    
    // Find and remove the unneeded strings
    $pattern = '/(\[A\]|\[B\]|\[C\])[^\[]*(\[A\]|\[B\]|\[C\])[^\[]*(\[A\]|\[B\]|\[C\])([^\[]*)(\[\/A\]|\[\/B\]|\[\/C\])[^\[]*(\[\/A\]|\[\/B\]|\[\/C\])[^\[]*(\[\/A\]|\[\/B\]|\[\/C\])/';
    preg_match_all( $pattern, $str, $matches );
    $stripped_str = $str;
    foreach ($matches[0] as $key=>$matched_pattern) {
      $matched_pattern_str  = str_replace($matches[4][$key], '', $matched_pattern); // matched pattern with text between A,B,C tags removed
      $stripped_str = str_replace($matched_pattern, $matched_pattern_str, $stripped_str); // replace pattern string in text with stripped pattern string
    }
    
    // Get required strings
    $pattern = '/(\[A\]|\[B\]|\[C\]|\[\/A\]|\[\/B\]|\[\/C\])([^\[]+)(\[A\]|\[B\]|\[C\]|\[\/A\]|\[\/B\]|\[\/C\])/';
    preg_match_all( $pattern, $stripped_str, $matches );
    $required_strings = array();
    foreach ($matches[2] as $match) {
      if (trim($match) != '') {
        $required_strings[] = $match;
      }
    }
    
    // Special case, possible string on start and end
    $pattern = '/^([^\[]*)(\[A\]|\[B\]|\[C\]).*(\[\/A\]|\[\/B\]|\[\/C\])([^\[]*)$/';
    preg_match( $pattern, $stripped_str, $matches );
    if (trim($matches[1]) != '') {
      $required_strings[] = $matches[1];
    }
    if (trim($matches[4]) != '') {
      $required_strings[] = $matches[4];
    }
    
    print_r($required_strings);
    

    【讨论】:

      猜你喜欢
      • 2012-08-29
      • 2012-02-19
      • 2018-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多