Search code examples
phparraysregexforeachpreg-match

PHP search and merge array elements if they have an identical substring


I have this php array:

Array (
     [0] =>
"BLABLABLA   08.09.15

 00.00.00  BBB  BBB  X3 0000  00:00   00:00
 00.00.00  BBB  BBB  TP 0000  00:00
 FNC015P blablablablablabla    blablabla
  1  blablabla     blablabla
 am blablabla blablabla
 blablabla blablabla blablabla
 blablabla
 blablabla
 bblablabla blablabla
 H999999  blablabla
blablabla
blablabla
blablabla
blablabla "


    [1] => 
"00.00.00  BBB  BBB  X3 0000  00:00   00:00
 00.00.00  BBB  BBB  TP 0000  00:00
 FNC015 blablablablablabla    blablabla
   blablablablablabla    blablabla
 blablablablablabla    blablabla
 blablablablablabla    blablabla
 blablablablablabla    
 blablablablablabla    bla
  blablablablablabla    blablabla
 H999996   blablablablablabla    blablabla
 blablablablablabla    bla
 blablablablablabla   
 blablablablablabla    blabla
 blablablablablabla    blablabla
 blablablablablabla    blablabla
 blablablablablabla    blablabla"

    [2] =>
"BLABLABLA   08.09.15
  00.00.00  BBB  BBB  X3 0000  00:00   00:00
 00.00.00  BBB  BBB  TP 0000  00:00
 FNC234  blablablablablabla    blablabla
 blablablablablabla    blablabla
blablablablablabla    blablabla
 blablab
 blablablablablabla    blablablablablablablablabla    blablabla
 blablab
H999999 blablablablablabla    blablabla
blablablablablabla    blablablablablablablablabla    blablabla"

[3] =>
"BLABLABLA   22.09.15
BLABLABLA
 22.09.15  STR  FNC  X3 2810  14:20   17:25
 29.09.15  FNC  STR  X3 2811  18:15
 FNC042  blablablablablabla    blablabla
 blablablablablabla    blablablablablablablablabla    blablabla
blablablablablabla    blablabla
blablab
 H999997  blablablablablabla    blablabla"
)

What I want to do is merge into one element the items that have the same H______. Like the folowing for the previous example:

 Array (
     [0] =>
"BLABLABLA   08.09.15

 00.00.00  BBB  BBB  X3 0000  00:00   00:00
 00.00.00  BBB  BBB  TP 0000  00:00
 FNC015P blablablablablabla    blablabla
  1  blablabla     blablabla
 am blablabla blablabla
 blablabla blablabla blablabla
 blablabla
 blablabla
 bblablabla blablabla
 H999999  blablabla
blablabla
blablabla
blablabla
blablabla 

+

"BLABLABLA   08.09.15
  00.00.00  BBB  BBB  X3 0000  00:00   00:00
 00.00.00  BBB  BBB  TP 0000  00:00
 FNC234  blablablablablabla    blablabla
 blablablablablabla    blablabla
blablablablablabla    blablabla
 blablab
 blablablablablabla    blablablablablablablablabla    blablabla
 blablab
H999999 blablablablablabla    blablabla
blablablablablabla    blablablablablablablablabla    blablabla"


    [1] => 
"00.00.00  BBB  BBB  X3 0000  00:00   00:00
 00.00.00  BBB  BBB  TP 0000  00:00
 FNC015 blablablablablabla    blablabla
   blablablablablabla    blablabla
 blablablablablabla    blablabla
 blablablablablabla    blablabla
 blablablablablabla    
 blablablablablabla    bla
  blablablablablabla    blablabla
 H999996   blablablablablabla    blablabla
 blablablablablabla    bla
 blablablablablabla   
 blablablablablabla    blabla
 blablablablablabla    blablabla
 blablablablablabla    blablabla
 blablablablablabla    blablabla"


[2] =>
"BLABLABLA   22.09.15
BLABLABLA
 22.09.15  STR  FNC  X3 2810  14:20   17:25
 29.09.15  FNC  STR  X3 2811  18:15
 FNC042  blablablablablabla    blablabla
 blablablablablabla    blablablablablablablablabla    blablabla
blablablablablabla    blablabla
blablab
 H999997  blablablablablabla    blablabla"
)

I have to find the item of the array the substring H_____ and compare with other items and if equal merge. I found examples of removing duplicates and finding exactly same item, but this is not the case. however unfortunately not always I have the same number of spaces, characters before and after the H______

I got the regex for the key: "#H\d+#" and I know that I need to use preg_match.

Can anyone help please?


Solution

  • See comments in code. The use of \b matches at a word boundary and prevents strings like XXH12345 from being matched.

    $a = [
        "This is one with H11111",
        "This is one that has an H22222    in it",
        "Tricky one WITH22222 in it",
        "This is another H11111, like the first one",
        "Here's a line without any number at all",
        "Here goes H33333",
        "H22222, finally."
    ];
    
    foreach ($a as $key => $element) {
        // Find any string matching H<digits> pattern
        if (preg_match('#\bH\d+\b#', $element, $numbers)) {
            $number = $numbers[0]; // Remember first found pattern
    
            if (!isset($keys[$number])) { // Do we know this from before?
                $keys[$number] = $key; // No, remember the index of this number
            }
            else {
                $a[$keys[$number]] .= " + " . $element; // Yes, append to existing value
                unset($a[$key]); // Then remove the appended element
            }
        }
    }
    print_r($a);
    

    Output:

    Array
    (
        [0] => This is one with H11111 + This is another H11111, like the first one
        [1] => This is one that has an H22222    in it + H22222, finally.
        [2] => Tricky one WITH22222 in it
        [4] => Here's a line without any number at all
        [5] => Here goes H33333
    )