0

Example input string: "[A][B][C]test1[/B][/C][/A] [A][B]test2[/B][/A] test3"

I need to find out what parts of text are NOT between the A, B and C tags. So, for example, in the above string it's 'test2' and 'test3'. 'test2' doesn't have the C tag and 'test3' doesn't have any tag at all.

If can also be nested like this: Example input string2: "[A][B][C]test1[/B][/C][/A] [A][B]test2[C]test4[/C][/B][/A] test3"

In this example "test4" was added but "test4" has the A,B and C tag so the output wouldn't change.

Anyone got an idea how I could parse this?

3
  • look into regular expressions Commented Sep 24, 2012 at 9:58
  • @Erik will the tags always be in the same order [A][B][C][/C][/B][A] ? Commented Sep 25, 2012 at 10:57
  • No, tags can be in any order and the closing tags can be in a different order than opening tags too Commented Sep 25, 2012 at 12:02

3 Answers 3

1

This solution is not clean but it does the trick

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

Output

 string 'test3' (length=5)
Sign up to request clarification or add additional context in comments.

Comments

0

Considering the fact that everyone of you tags is in [A][/A] What you can do is: Explode the [/A] and verify if each array contains the [A] tag like so:

$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

1 Comment

this won't work. Does not support nested tags and even the output is wrong as "test2" is not within the [C] tags so it should have been found too... I don't think it can be done with a simple explode()
0

try the below code

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.