I have a set of number/barcode that need to split and convert into the readable information. I try the code below but not able to extract the information after the digit serial no (21). batch no (10) will contain variable length.
How to split the serial no is to the table column?
The format sequel will be 01 , 17 ,10 ,21 & 11 01 - gtin (14 DIGIT only) 17 - expire date (YYMMDD) 10 - batch no (can be variable but not more than 20 digit) 21 - serial no (can be variable but not more than 20 digit) 11 - production date (YYMMDD)
scanned barcode information = 010955613508230117220721106022196721Sk4YGvF8
strtemp = "010955613508230117220721106022196721Sk4YGvF8"
if ($strtemp != null){
$ais = explode("_",$strtemp);
for ($aa=0;$aa<sizeof($ais);$aa )
{
$ary = $ais[$aa];
while(strlen($ary) > 0) {
if (substr($ary,0,2)=="01"){
$igtin = substr($ary,2,14);
$ary = substr($ary,-(strlen($ary)-16));
}
else if (substr($ary,0,2)=="17"){
$expirydate = substr($ary,6,2)."-".substr($ary,4,2)."-20".substr($ary,2,2);
$ary = substr($ary,-(strlen($ary)-8));
}
else if (substr($ary,0,2)=="10"){
$batchno = substr($ary,2,strlen($ary)-2);
$ary = "";
}
else if (substr($ary,0,2)=="21"){
$serialno = substr($ary,2,strlen($ary)-2);
$ary = "";
}
else if (substr($ary,0,2)=="11"){
$proddate = substr($ary,6,2)."-".substr($ary,4,2)."-20".substr($ary,2,2);
$ary = substr($ary,-(strlen($ary)-8));
}
else {
$oth = "";
}
}
The result I want should be as below:-
Items | Result |
---|---|
GTIN | 09556135082301 |
EXPIRE DATE | 21-07-2022 |
BATCH/LOT NUMBER | 60221967 |
SERIAL NUMBER | Sk4YGvF8 |
But, Output from the coding above is like this:-
Items | Result |
---|---|
GTIN | 09556135082301 |
EXPIRE DATE | 21-07-2022 |
BATCH/LOT NUMBER | 6022196721Sk4YGvF8 |
SERIAL NUMBER |
Any ideas why my coding didn't work? Possible to split the number after 21 and display as serial number?
CodePudding user response:
Your code is a little long and too clumsy to read and debug. Instead, I propose another approach with a regex as regex seems to be the right tool for this.
Split the string with
/(?=\(\d \))/
which is a positive lookahead assertion splitting the string based on(some code) some string
pattern.Now, for each one, capture the starting code as key and rest as the value using another regex
/^(\(\d \))(. )$/
. This matches the starting code followed by any character 1 or more times.
Snippet:
<?php
$str = '(01)09556135082301(17)220721(10)60221967(21)Sk4YGvF8';
$result = [];
foreach(preg_split('/(?=\(\d \))/', $str) as $match){
$matches = [];
if(preg_match('/^(\(\d \))(. )$/', $match, $matches) === 1){
$result[ $matches[1] ] = $matches[2];
}
}
print_r($result);
Note: You can later split the value at key (17)
to get yourself that date format.
CodePudding user response:
else if (substr($ary,0,2)=="10"){
$batchno = substr($ary,2,strlen($ary)-2);
$ary = "";
}
To answer your question. The reason is when "10" is found, the remaining string is used. you need do what you've done in other branches.
Give you some advice. Your approach is hard to read, you'd better use for
and switch
to optimze the code like this:
for($i = 0; $i < strlen($ary); )
{
$h = substr($ary, $i, 2);
$i = 2;
switch($h)
{
case '01':
$igtin = substr($ary,$i,14);
$i = 14;
break;
case '10':
.......
}
}