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:
- 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);
- 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';
- Use
preg_match_all
with thePREG_UNMATCHED_AS_NULL
flag: when the optional value group isn't matched, the returned value isnull
instead of an empty string.
With thepreg_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(?, '')