简体   繁体   English

将条形码扫描字符串转换为变量

[英]Convert barcode scan string to variables

I have a barcode that after being scanned it needs to be split into five variables.我有一个条形码,在扫描后需要将其分成五个变量。

Example barcode scan: 0109556135082301172207211060221967 21Sk4YGvF8
Alternate scan: 010955704600017017250630102107015

There are 5 delimiters有5个分隔符

01 - gtin (14 DIGIT only)
11 - production date (YYMMDD)
17 -  expire date (YYMMDD)
10 - batch no (can be variable but not more than 20 digit)  
<space>21 - serial no (can be variable but not more than 20 digit)


01
09556135082301 (gtin)
17
220721 (production date)
10
60221967 (batch number)
 21
Sk4YGvF8 (serial number)

This is my attempt:这是我的尝试:

$str = "0109556135082301172207211060221967 21Sk4YGvF8"

if ($strtemp != null){
    $ais = explode("_",$str);
    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 desired:想要的结果:

Items项目 Result结果
GTIN GTIN 09556135082301 09556135082301
EXPIRE DATE到期日期 21-07-2022 21-07-2022
BATCH/LOT NUMBER批号 60221967 60221967
SERIAL NUMBER序列号 Sk4YGvF8 Sk4YGvF8

From my code above the variable come out like this:从我上面的变量代码中得出这样的结果:

Items项目 Result结果
GTIN GTIN 09556135082301 09556135082301
EXPIRE DATE到期日期 21-07-2022 21-07-2022
BATCH/LOT NUMBER批号 6022196721Sk4YGvF8 6022196721Sk4YGvF8
SERIAL NUMBER序列号
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.原因是当找到“10”时,使用剩余的字符串。 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:您的方法很难阅读,您最好forswitch到优化代码,如下所示:

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':
        .......
    }
}

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./(?=\(\d+\))/拆分字符串,这是一个基于(some code) some string模式的正向先行断言拆分字符串。

  • Now, for each one, capture the starting code as key and rest as the value using another regex /^(\(\d+\))(.+)$/ .现在,对于每一个,使用另一个正则表达式/^(\(\d+\))(.+)$/将起始代码捕获为键,并将 rest 作为值。 This matches the starting code followed by any character 1 or more times.这匹配起始代码后跟任何字符 1 次或多次。

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);

Online Demo .在线演示

Note: You can later split the value at key (17) to get yourself that date format.注意:您可以稍后拆分键(17)处的值以获得该日期格式。

I think I may have it.我想我可能拥有它。

01
09556135082301
17
220721
10
60221967
21
Sk4YGvF8

Getting the gtin and expires is simple due to the fixed value lengths.由于固定值长度,获取 gtin 和 expires 很简单。
Presuming "21" will not show up in the serial number.假设“21”不会出现在序列号中。 strrpos finds the last position of "21" in $str. strrpos 在 $str 中找到“21”的最后一个 position。 So serial number is from that position + 2 where +2 is for the length of "21" and take the substring from that position to the end.所以序列号来自 position + 2 ,其中 +2 是“21”的长度,并从 position 中取出 substring 到最后。
The use the end position of the expires to the position of "21" to get the $batch.使用过期的 position 到 "21" 的 position 得到 $batch。

$len = strlen($str);
$gtin = substr($str,2,14);
$expires = substr(18,6);
$position = strrpos('21', $str) + 2;
$serial = substr($str,$position);
$batch = substr($str,24,$len - $position); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM