Home > Blockchain >  preg_match_all loop for each match, verify if empty to set null values to insert in table mysql
preg_match_all loop for each match, verify if empty to set null values to insert in table mysql

Time:11-24

I have 10 lines to extract from file text, some are empty but exist, others don't exist but I have to insert them anyway, with regex can split text by 10 group, i use preg_match_all to match group and generate a array with matches, but if the lines not exist not matched, i want insert values group to insert in mysql table and if the value is empty set a NULL.

I just need them only values, but first verify if keys exist and add missing keys and NULL values for this.

https://regex101.com/r/pwPqUu/1

$re = '/.*(?:APPLICATION ID).*|.*(?:STATUS P=PENDING\/A=ACTIVE).*|.*(?:VALID-TO DATE).*|.*(?:APPLICATION TYPE \(A\/G\)).*|.*(?:DESCRIPTIVE TEXT).*|.*(?:OWNER ID).*|.*(?:PERIOD OR RUN CYCLE GROUP NAME).*|.*(?:RUN CYCLE VALID-FROM).*|.*(?:RUN CYCLE VALID-TO).*|.*(?:RUN CYCLE DESCRIPTION).*/';

$str = '
      APPLICATION ID                   :AAAAA#AA#0101       
      STATUS P=PENDING/A=ACTIVE        :A                    
      VALID-TO DATE                    :711231               
      APPLICATION TYPE (A/G)           :A                    
      DESCRIPTIVE TEXT                 :DESC folder AAAAA    
      OWNER ID                         :               
      RANDOM INFO                      :                     
            PERIOD OR RUN CYCLE GROUP NAME   :QAZ123XX        
            RUN CYCLE VALID-FROM             :711230          
            RUN CYCLE VALID-TO               :711231          
            RUN CYCLE DESCRIPTION            :MANUAL ORDER    
            RUN RANDOM IFO                   :                
      APPLICATION ID                   :BBBBB#BB#0101       
      STATUS P=PENDING/A=ACTIVE        :A                    
      VALID-TO DATE                    :711231               
      APPLICATION TYPE (A/G)           :A                    
      DESCRIPTIVE TEXT                 :                     
      OWNER ID                         :OWNER1               
      RANDOM INFO                      :                     
';

preg_match_all($re, $str, $matches);

// Print the entire match result
echo '<pre>' . print_r( $matches, true ) . '</pre>';

the result is:

Array
(
    [0] => Array
        (
            [0] =>       APPLICATION ID                   :AAAAA#AA#0101       
            [1] =>       STATUS P=PENDING/A=ACTIVE        :A                    
            [2] =>       VALID-TO DATE                    :711231               
            [3] =>       APPLICATION TYPE (A/G)           :A                    
            [4] =>       DESCRIPTIVE TEXT                 :DESC folder AAAAA    
            [5] =>       OWNER ID                         :               
            [6] =>             PERIOD OR RUN CYCLE GROUP NAME   :QAZ123XX        
            [7] =>             RUN CYCLE VALID-FROM             :711230          
            [8] =>             RUN CYCLE VALID-TO               :711231          
            [9] =>             RUN CYCLE DESCRIPTION            :MANUAL ORDER    
            [10] =>       APPLICATION ID                   :BBBBB#BB#0101       
            [11] =>       STATUS P=PENDING/A=ACTIVE        :A                    
            [12] =>       VALID-TO DATE                    :711231               
            [13] =>       APPLICATION TYPE (A/G)           :A                    
            [14] =>       DESCRIPTIVE TEXT                 :                     
            [15] =>       OWNER ID                         :OWNER1               
        )

)

the result should be:

if the value is empty set NULL, if the group not exist in text file add a values to set a NULL to insert in table mysql. (keys 5, 14, 16, 17, 18, 19)

only values insert to mysql table.

Array
(
    [0] => Array
        (
            [0] =>       APPLICATION ID                   :AAAAA#AA#0101       
            [1] =>       STATUS P=PENDING/A=ACTIVE        :A                    
            [2] =>       VALID-TO DATE                    :711231               
            [3] =>       APPLICATION TYPE (A/G)           :A                    
            [4] =>       DESCRIPTIVE TEXT                 :DESC folder AAAAA    
            [5] =>       OWNER ID                         :NULL               
            [6] =>             PERIOD OR RUN CYCLE GROUP NAME   :QAZ123XX        
            [7] =>             RUN CYCLE VALID-FROM             :711230          
            [8] =>             RUN CYCLE VALID-TO               :711231          
            [9] =>             RUN CYCLE DESCRIPTION            :MANUAL ORDER    
            [10] =>       APPLICATION ID                   :BBBBB#BB#0101       
            [11] =>       STATUS P=PENDING/A=ACTIVE        :A                    
            [12] =>       VALID-TO DATE                    :711231               
            [13] =>       APPLICATION TYPE (A/G)           :A                    
            [14] =>       DESCRIPTIVE TEXT                 :NULL                     
            [15] =>       OWNER ID                         :OWNER1               
            [16] =>             PERIOD OR RUN CYCLE GROUP NAME   :NULL        
            [17] =>             RUN CYCLE VALID-FROM             :NULL          
            [18] =>             RUN CYCLE VALID-TO               :NULL          
            [19] =>             RUN CYCLE DESCRIPTION            :NULL  
        )

)

i should use array_push, array_key_exists or in the regex assign a name by each group?

and the last, how to loop each matches? with preg_match_all generate only one array with full match, but my table mysql only 10 columns one for each group regex.

thanks

Regards.

Italo.

CodePudding user response:

  1. Build an array with all needed keys and values set to null:
$columns = [
    'APPLICATION ID',
    'STATUS P=PENDING/A=ACTIVE',
    /*...*/
    'RUN CYCLE DESCRIPTION'
];

$keys = array_fill_keys($columns, null);
  1. Build a pattern to extract keys and values present in your string. To do that, it's totally useless to put all the needed keys in your pattern, you just need to use capture groups (named here) to isolate keys from values for each match (note that the value group is optional):
$pat = '~^ \h*  (?<key> [^:\n]* [^:\s] ) \h* : (?<value> \S  (?:\h \S )* )? ~xm';
  1. Use preg_match_all with the PREG_UNMATCHED_AS_NULL flag: when the optional value group isn't matched, the returned value is null instead of an empty string.
    With the preg_match_all match results, build an associative array with the $matches['key'] and $matches['value'] subarrays (note that this one has the same keys than the array $keys except that eventually some keys are missing).
    Then all you have to do is to merge the $keys array with this new array to obtain an associative array with the key/value pairs you are interested by.
if ( preg_match_all($pat, $yourstring, $matches, PREG_UNMATCHED_AS_NULL) ) {
    $result = array_combine($matches['key'], $matches['value']);
    $result = array_merge($keys, $result);
}

1,2,3 Aquafresh® 3

CodePudding user response:

I would process this in multiple steps:

$str = '
      APPLICATION ID                   :AAAAA#AA#0101       
      STATUS P=PENDING/A=ACTIVE        :A                    
      VALID-TO DATE                    :711231               
      APPLICATION TYPE (A/G)           :A                    
      DESCRIPTIVE TEXT                 :DESC folder AAAAA    
      OWNER ID                         :               
      RANDOM INFO                      :                     
            PERIOD OR RUN CYCLE GROUP NAME   :QAZ123XX        
            RUN CYCLE VALID-FROM             :711230          
            RUN CYCLE VALID-TO               :711231          
            RUN CYCLE DESCRIPTION            :MANUAL ORDER    
            RUN RANDOM IFO                   :                
      APPLICATION ID                   :BBBBB#BB#0101       
      STATUS P=PENDING/A=ACTIVE        :A                    
      VALID-TO DATE                    :711231               
      APPLICATION TYPE (A/G)           :A                    
      DESCRIPTIVE TEXT                 :                     
      OWNER ID                         :OWNER1               
      RANDOM INFO                      :                     
';

plus

$groups = explode('APPLICATION ID', $str);
foreach ($groups as $group) {
    echo "----\n";
    $hash = [];
    if (empty($group)) continue;
    $group = 'APPLICATION ID' . $group;
    $lines = preg_split("/\n/m", $group);
    foreach($lines as $line) {
        $kv = explode(':', $line);
       if (count($kv) == 2 && trim($kv[1]) != '')
            $hash[trim($kv[0])] = trim($kv[1]);
    }
    print_r($hash);

    // TODO:  Build an INSERT with just the values in $hash
    // Meanwhile, each column should be `DEFAULT NULL`.
}

Yields:

----
Array
(
)
----
Array
(
    [APPLICATION ID] => AAAAA#AA#0101
    [STATUS P=PENDING/A=ACTIVE] => A
    [VALID-TO DATE] => 711231
    [APPLICATION TYPE (A/G)] => A
    [DESCRIPTIVE TEXT] => DESC folder AAAAA
    [PERIOD OR RUN CYCLE GROUP NAME] => QAZ123XX
    [RUN CYCLE VALID-FROM] => 711230
    [RUN CYCLE VALID-TO] => 711231
    [RUN CYCLE DESCRIPTION] => MANUAL ORDER
)
----
Array
(
    [APPLICATION ID] => BBBBB#BB#0101
    [STATUS P=PENDING/A=ACTIVE] => A
    [VALID-TO DATE] => 711231
    [APPLICATION TYPE (A/G)] => A
    [OWNER ID] => OWNER1
)

Another tip: NULLIF(?, '')

  • Related