2

I have a string:

$string = 'A0695/16 NOTAMN Q) EHAA/QARLT/I /NBO/E /000/999/5155N00430E073 A) EHAA B) 1605260001 C) 1608260900 EST E) REF AIP NETHERLANDS ENR 3.2 UT601 ADD TO ROUTE REMARKS: NOT AVBL FOR TRAFFIC DEP/ARR ETNG, EDDK AND ETNN DURING THE OPENING OF EHEH 0600-2300 (0500-2200). THESE FLIGHTS WILL HAVE TO REROUTE.';

I would like to split this string into an associative array.

$result['Q)'] = 'EHAA/QARLT/I /NBO/E /000/999/5155N00430E073';
$result['A)'] = 'EHAA';
$result['B)'] = '1605260001';
$result['C)'] = '1608260900 EST';

etc.

I managed to get it into an array with:

$result = preg_split("/.\)/", $string);

It gives me an array but I need the keys to be 'a)', 'b)' etc.

Can anyone help me with this?

1
  • It might be better to take a step back an look at how you created that string, maybe that would be a better place to make a change Commented Aug 6, 2016 at 15:15

3 Answers 3

2

The solution using preg_match_all function with specific regexp pattern(named submasks) and array_combine function(to get a respective key/value pairs):

$string = 'A0695/16 NOTAMN Q) EHAA/QARLT/I /NBO/E /000/999/5155N00430E073 A) EHAA B) 1605260001 C) 1608260900 EST E) REF AIP NETHERLANDS ENR 3.2 UT601 ADD TO ROUTE REMARKS: NOT AVBL FOR TRAFFIC DEP/ARR ETNG, EDDK AND ETNN DURING THE OPENING OF EHEH 0600-2300 (0500-2200). THESE FLIGHTS WILL HAVE TO REROUTE.';

preg_match_all("/(?<k>[A-Z]\)) (?<v>.+?)(?= [A-Z]\)|$)/", $string, $matches);

// 'k'/'v' are key/value
$result = array_combine($matches['k'], $matches['v']);

print_r($result);

The output:

Array
(
    [Q)] => EHAA/QARLT/I /NBO/E /000/999/5155N00430E073
    [A)] => EHAA
    [B)] => 1605260001
    [C)] => 1608260900 EST
    [E)] => REF AIP NETHERLANDS ENR 3.2 UT601 ADD TO ROUTE REMARKS: NOT AVBL FOR TRAFFIC DEP/ARR ETNG, EDDK AND ETNN DURING THE OPENING OF EHEH 0600-2300 (0500-2200). THESE FLIGHTS WILL HAVE TO REROUTE.
)
Sign up to request clarification or add additional context in comments.

2 Comments

Your way is clearly the best. Note that you can remove the option PREG_SET_ORDER and build the result without using foreach, like this: $result = array_combine($matches['k'], $matches['v']);
@CasimiretHippolyte, thanks for the useful hint. I've simplified the answer
1

Another goofy solution for the goofy format, because why not.

  $string = 'A0695/16 NOTAMN Q) EHAA/QARLT/I /NBO/E /000/999/5155N00430E073 A) EHAA B) 1605260001 C) 1608260900 EST E) REF AIP NETHERLANDS ENR 3.2 UT601 ADD TO ROUTE REMARKS: NOT AVBL FOR TRAFFIC DEP/ARR ETNG, EDDK AND ETNN DURING THE OPENING OF EHEH 0600-2300 (0500-2200). THESE FLIGHTS WILL HAVE TO REROUTE.';

  $foo = preg_split('/([A-Z]\)) /', $string, 0, PREG_SPLIT_DELIM_CAPTURE);
  $ret = [];
  foreach (range(1, count($foo) - 1, 2) as $i)
  {
    $ret[$foo[$i]] = $foo[$i + 1];
  }
  print_r($ret);

Prints:

Array (
    [Q)] => EHAA/QARLT/I /NBO/E /000/999/5155N00430E073 
    [A)] => EHAA 
    [B)] => 1605260001 
    [C)] => 1608260900 EST 
    [E)] => REF AIP NETHERLANDS ENR 3.2 UT601 ADD TO ROUTE REMARKS: NOT AVBL FOR TRAFFIC DEP/ARR ETNG, EDDK AND ETNN DURING THE OPENING OF EHEH 0600-2300 (0500-2200). THESE FLIGHTS WILL HAVE TO REROUTE. )

Comments

0

More fanciful than efficient but it does the job:

$p = preg_split('~(?<!\S)([A-Z]\))\s+~', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
$result = [];
if (count($p) > 1) {
    unset($p[0]);
    while($p) { 
        $result[array_shift($p)] = array_shift($p);
    }
}

print_r($result);

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.