PHP:如何查找不在特定标记之间的文本?

PHP:如何查找不在特定标记之间的文本?,php,parsing,text,tags,Php,Parsing,Text,Tags,输入字符串示例:“[A][B][C]test1[/B][C][A][B]test2[/B][A]test3” 我需要找出文本的哪些部分不在A、B和C标记之间。例如,在上面的字符串中是'test2'和'test3'test2'没有C标记,“test3”根本没有任何标记 If也可以像这样嵌套: 示例输入字符串2:“[A][B][C]test1[/B][C][A][B]test2[C]test4[/C][B][A]test3” 在本例中添加了“test4”,但“test4”具有A、B和C标记,因此输出

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

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

If也可以像这样嵌套: 示例输入字符串2:“[A][B][C]test1[/B][C][A][B]test2[C]test4[/C][B][A]test3”

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


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

这个解决方案并不干净,但它确实做到了

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

考虑到每个标记都在[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
请尝试下面的代码

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

调查常规expressions@Erik标签的顺序是否始终相同?不,标签的顺序可以是任意的,结束标签的顺序可以与开始标签的顺序不同,因为牙齿不起作用。不支持嵌套标记,甚至输出也是错误的,因为“test2”不在[C]标记中,所以也应该找到它。。。我不认为用一个简单的爆炸就可以做到
$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);