Question

I want to put this string into an array. Every element should container the content of a bracket. So is there a simple way to do this?

(aka "Beep My Dad Says" (2010)) (USA) (alternative title)
 ----------------------------   -----   ----------------
            array[0]            array[1]    array[2]

Have already tried something like

$str = '(aka "Beep My Dad Says" (2010)) (USA) (alternative title)';

if (preg_match("/\(.*?\)/", $str, $matches)) {
    echo $matches[0];
}
Was it helpful?

Solution

Heres how to do it

$string = '(aka "Beep My Dad Says" (2010)) (USA) (alternative title)';

$brackets  = array();

$words = array();
$start = 0;


for($i=0; $i<strlen($string) ; $i++)
{

    if($string[$i]=="(")
    {
      array_push($brackets,"(");


    }
    if($string[$i]==")")
    {
      array_pop($brackets);

    }
    if(count($brackets)==0)
    {

        array_push($words,substr($string,$start+1,$i-$start-1));

    $start = $i+2;
    $i++;
    }

}
print_r($words);

OTHER TIPS

You're just complicating it. Following will do it

$arr = explode(') (', trim('(aka "Beep My Dad Says" (2010)) (USA) (alternative title)', '()'));

RegEx is on the right path. Just include a + modifier to greedily collect any trailing embedded brackets.

$str = '(aka "Beep My Dad Says" (2010)) (USA) (alternative title)';
/* Regex */
preg_match_all('!\(.*?\)+!',$str,$match);

var_dump($match[0]);
/*
array(3) {
  [0] =>
  string(31) "(aka "Beep My Dad Says" (2010))"
  [1] =>
  string(5) "(USA)"
  [2] =>
  string(19) "(alternative title)"
}
*/

But this will not work for other embedded quotes, and whitespace between segments should't be trusted. A primitive lexer might be a better approach.

$str = '(aka "Beep My (Dad) Says" (2010)) (USA)(alternative title)';
/* Lexer/Scanner */
$length = strlen($str);
$stack = array();
$cursor = $nested = 0;
$top = -1;
while ( $cursor < $length ) {
 $c = $str[$cursor++];     // Grab char at index.
 if ( '(' == $c ) {        // Scan for starting character.
   if ( !$nested )         // Check if this is the start of a new segment.
     $stack[++$top] = "";  // Prototype new buffer (i.e. empty string).
  $nested++;               // Increase nesting.
 }
 if ( $nested )
   $stack[$top] .= $c;     // Append character, if inside brackets.
 if ( ')' == $c )          // Scan for ending character.
   $nested--;              // Decrease nesting.
}

var_dump($stack);
/*
array(3) {
  [0] =>
  string(33) "(aka "Beep My (Dad) Says" (2010))"
  [1] =>
  string(5) "(USA)"
  [2] =>
  string(19) "(alternative title)"
}
*/

Again, this will just punt the problem down field, as fields that include uneven brackets will confuse any regular expression, or lexer.

$str = '(Sunn O))) "NN O)))" (2000)) (USA) (drone metal)';

Ideally, you would want to return to the source generator, and include escaping (if possible).

$str = '(aka "Beep My Dad Says" \(2010\)) (USA) (alternative title)';

Simple is best

list($part1, $part2, $part3) = explode(') ', $string);

// Note the space after closing bracket - which is the trick to this

You could then run them through a ltrim('(') and rtrim(')') to remove the brackets from the array if they are not wanted.

Try this, I've tested it with the string you provided, this extracts what you need regardless of spaces:

public function stringToArray ( $startingCharacter, $endingCharacter, $string ) {
    $startCounter = 0;
    $strLen = strlen($string);
    $arrayResult = array();

    for ( $i = 0 ; $i < $strLen ; $i++ ) {
        if ( $string[$i] == $startingCharacter ) {
            if ( $startCounter == 0 ) {
                $startingPosition = $i + 1;
            }
            $startCounter++;
        }

        if ( $string[$i] == $endingCharacter && $startCounter == 1 ) {
            $startCounter--;
            $arrayResult[] = substr( $string, $startingPosition , ( $i - $startingPosition ) );
        }
        else if ( $string[$i] == $endingCharacter ) {
            $startCounter--;
        }
    }
}

And here's without the function format:

$string = '(aka "Beep My Dad Says" (2010))(USA)(alternative title)';

$startingCharacter = '(';
$endingCharacter = ')';
$startCounter = 0;
$strLen = strlen($string);
$arrayResult = array();

for ( $i = 0 ; $i < $strLen ; $i++ ) {
    if ( $string[$i] == $startingCharacter ) {
        if ( $startCounter == 0 ) {
            $startingPosition = $i + 1;
        }
        $startCounter++;
    }

    if ( $string[$i] == $endingCharacter && $startCounter == 1 ) {
        $startCounter--;
        $arrayResult[] = substr( $string, $startingPosition , ( $i - $startingPosition ) );
    }
    else if ( $string[$i] == $endingCharacter ) {
        $startCounter--;
    }
}

Hope it helps :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top