Skip to content
Advertisement

Split strings in array to form three-element subarrays

I am practising with the AdventureWorks database for now and I will be receiving strings like the following: SalesOrderNumber=SOH123 and CustomerID=1. The strings may not always contain =, as they may be >, <, >=, <=, !=, <>.

Ideally, I would like to split each string into 3 fields – the database column to query, the comparison (e.g. =, >, !=, etc) and the value to search for.

I can achieve what I want with lots of code, comparing character by character, but I am hoping someone can suggest a really simple way to do this, as I am sure this must be a fairly common task for websites.

I don’t want to just use the strings as they come through, as I need to sanitise them first. I also don’t want to send bad queries to the database that may generate SQL errors.

Advertisement

Answer

It is indirect and feasibly inefficient to make calls of explode() within nested loops with break condition.

I recommend preg_split() as the right tool for the job. Create a capture group containing a character class of whitelisted symbols. Allow a maximum of 3 elements as its return value. Use the PREG_SPLIT_DELIM_CAPTURE flag to inform the function to preserve the delimiting comparison operators when exploding the string into three parts.

Code: (Demo)

var_export(
    array_map(
        fn($v) => preg_split(
            '/([!<=>]+)/',
            $v,
            3,
            PREG_SPLIT_DELIM_CAPTURE
        ),
        $array
    )
);

Output:

array (
  0 => 
  array (
    0 => 'SalesOrderNumber',
    1 => '=',
    2 => 'SOH123',
  ),
  1 => 
  array (
    0 => 'CustomerID',
    1 => '=',
    2 => '1',
  ),
  2 => 
  array (
    0 => 'BigOrEqual',
    1 => '>=',
    2 => '44',
  ),
  3 => 
  array (
    0 => 'SmallOrEqual',
    1 => '<=',
    2 => '67',
  ),
  4 => 
  array (
    0 => 'NotEqual',
    1 => '!=',
    2 => '123',
  ),
  5 => 
  array (
    0 => 'NotEqual',
    1 => '<>',
    2 => '2000',
  ),
  6 => 
  array (
    0 => 'Smaller',
    1 => '<',
    2 => '21',
  ),
  7 => 
  array (
    0 => 'Bigger',
    1 => '>',
    2 => '12',
  ),
)
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement