skip to Main Content

After modifying a query result, I end up with an array like the following example:

[0] => foo (bar1)
[1] => bar (foo2)
[2] => bas
[3] => foo (bas3)
[4] => bar

As you can see, some of the values contain parentheses, some don’t.

I need the parentheses part of each value in an own (new) array. The key should be retained. If there are no parentheses in the value of the first array, the value in the second array should be   instead. The array keys in both arrays should be identical. The second array should therefore look like this:

[0] => (bar1)
[1] => (foo2)
[2] => 
[3] => (bas3)
[4] => 

Up to now I got this PHP code:

$pattern = "/((.*?))/";  //Looks for text in parentheses
$array1 = <see above>
$array2 = array();     //The second array, which should contain the extracted parentheses parts
foreach($array1 as $index => $value) {
  $array2 = preg_grep($pattern,$array1);
}

This works fine, but it displays the whole value of $array1 as value in $array2, when parentheses are found. Values in $array1 without parentheses are missing completely.
I cannot come up with a solution to only extract the (…)-part, remove it from $array1 and add &nbsp; to $array2 if no parentheses are detected. I tried using preg_match to achieve this, but that gave me an array to string conversion error.

Does anyone have an idea how to get this problem solved?

5

Answers


  1. You could use a regex on each element.

    This will find an open parenthesis. followed by any characters until a closed parenthesis. When found, the first match will be returned else a &nbsp;.

    print_r(array_map(
        fn($item) => preg_match('/((.*?))/', $item, $matches) ? $matches[1] : '&nbsp;', 
        ['foo (bar1)', 'bar (foo2)', 'bas', 'foo (bas3)', 'bar']
    ));
    
    Array
    (
        [0] => (bar1)
        [1] => (foo2)
        [2] => &nbsp;
        [3] => (bas3)
        [4] => &nbsp;
    )
    
    Login or Signup to reply.
  2. This might help

    $pattern = "/((.*?))/";  
    $array1 = [];
    $array2 = array();  
    foreach ($array1 as $index => $value) {
        preg_match($pattern, $value, $matches);  
        if (isset($matches[1])) {
            $array2[$index] = str_replace($matches[0], "", $value); 
        } else {
            $array2[$index] = $value;  
        }
    }
    print_r($array2);
    
    Login or Signup to reply.
  3. A variant using array_walk():

    <?php
    $input = [
      0 => "foo (bar1)",
      1 => "bar (foo2)",
      2 => "bas",
      3 => "foo (bas3)",
      4 => "bar",
    ];
    
    $output = [];
    array_walk($input, function($entry, $key) use (&$output) {
      $output[$key] = preg_match('|([^)]*)|', $entry, $token) ? $token[0] : "&nbsp;";
    });
    
    print_r($output);
    

    The output obviously is:

    Array
    (
        [0] => (bar1)
        [1] => (foo2)
        [2] => &nbsp;
        [3] => (bas3)
        [4] => &nbsp;
    )
    
    Login or Signup to reply.
  4. With foreach and a formatted string:

    $arr = ['foo (bar1)', 'bar (foo2)', 'bas', 'foo (bas3)', 'bar'];
    $res = [];
    
    foreach($arr as $k => $v) {
        sscanf($v, '%[^ (] %s', $arr[$k], $res[$k]);
        $res[$k] = $res[$k] ?? ''; // or '&nbsp;'
    }
    
    print_r($arr);
    print_r($res);
    
    Login or Signup to reply.
  5. I think most simply, this task is a good candidate for iterated calls of strstr() (strpbrk() has the same functionality with a character mask). If the sought opening parenthesis is not found, fallback to the &nbsp;.

    Code: (Demo)

    var_export(
        array_map(fn($v) => strstr($v, '(') ?: '&nbsp;', $array)
    );
    

    As a deviation from Casimir’s sscanf() solution, I prefer to use array_map() and ignore the substring before the parentheses while parsing (using *).

    Upon attempting to parse each string, the function will return a single-element array with either null, or the parenthetical value. If null fallback to the desired &nbsp; string.

    In the parsing pattern, %*[^(] means match but do not retain characters from the start of the string to the first occurring opening parenthesis. Then the %s will match and retain all subsequent non-whitespace characters. That retained parenthetical substring can be accessed as the first element in sscanf()‘s returned array.

    Code: (Demo)

    var_export(
        array_map(fn($v) => sscanf($v, '%*[^(]%s')[0] ?? '&nbsp;', $array)
    );
    

    The regex version of this is: (Demo)

    var_export(
        array_map(fn($v) => preg_replace('/[^(]*(.*)/', '$1', $v) ?: '&nbsp;', $array)
    );
    

    Or with preg_match(): (Demo)

    var_export(
        array_map(fn($v) => preg_match('/(.+)/', $v, $m) ? $m[0] : '&nbsp;', $array)
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search