在 OCR 获得的收据中查找总数 - PHP

Find the total in a receipt got by OCR - PHP

我在通过 API 视觉获得的收据字符串中查找用户支付的总额时遇到问题。

例如:

$testo2 = "Del burger Sr Via Carlo del Prete 106/d 50127 FIRENZE C.F. E P.IVA 08380120482 BRUNCH MAMMAMIA ONION RINGS SPICCHI PATATE ACQUA 0.5L TAVOLO 88 EURO 6,50 6,50 4,00 3,00 1,00 TOTALE EURO CONTANTI 21,00 21,00 NR.0057 23/05/18 20:21 MF U1 72005985";

为了找到总数,我尝试在 a 中搜索点或逗号(有些收据有点和另一个逗号),然后检查点或逗号后是否有两个数字,然后过一会儿在逗号之前搜索数字,直到找到的字符是一个数字。然后我将这些值放入一个数组中并以这样的方式反转它以组成一个完整的价格字符串(包括逗号后面的值)。然后将价格输入数组。

 for($i = 1; $i <= $lenghtTesto2 - 1; $i++)
{
   if($testo2[$i] == "." || $testo2[$i] == ",")
   {
      if($testo2[$i + 1] == "0" || $testo2[$i + 1] == "1" || $testo2[$i + 1] == "2" || $testo2[$i + 1] == "3" || $testo2[$i + 1] == "4" || $testo2[$i + 1] == "5" || $testo2[$i + 1] == "6" || $testo2[$i + 1] == "7" || $testo2[$i + 1] == "8" || $testo2[$i + 1] == "9")
      {
         if($testo2[$i + 2] == "0" || $testo2[$i + 2] == "1" || $testo2[$i + 2] == "2" || $testo2[$i + 2] == "3" || $testo2[$i + 2] == "4" || $testo2[$i + 2] == "5" || $testo2[$i + 2] == "6" || $testo2[$i + 2] == "7" || $testo2[$i + 2] == "8" || $testo2[$i + 2] == "9")
         { 

          $check = true;
          while($check)
          {
              if($testo2[$i - $j] == "0" || $testo2[$i - $j] == "1" || $testo2[$i - $j] == "2" || $testo2[$i - $j] == "3" || $testo2[$i - $j] == "4" || $testo2[$i - $j] == "5" || $testo2[$i - $j] == "6" || $testo2[$i - $j] == "7" || $testo2[$i - $j] == "8" || $testo2[$i - $j] == "9")
              {          


                array_push($arrPrezzi_invertiti, $testo2[$i - $j]);

                $j++;

              }
              else
              {
                 $prezzo = "";
                 $totaleFinale = "";
                 $dopoPunto1 = $testo2[$i + 1];
                 $dopoPunto2 = $testo2[$i + 2];
                 $j = 1;
                 $lenght_arrPrezzi_invertiti = count($arrPrezzi_invertiti);


                 for($k = $lenght_arrPrezzi_invertiti - 1; $k >= 0; $k--)
                 {
                     $totaleFinale .= $arrPrezzi_invertiti[$k];

                 }

                 $prezzo = $totaleFinale . "." . $dopoPunto1 . $dopoPunto2;

                 array_push($array, $prezzo);

                 $check = false;
              }   
          }              
     }
  }
}
}

钱是 6,50 6,50 4,00 3,00 1,00 21,00 21,00

提前致谢。

使用preg_match();

您必须将可能的单词组合添加到 [\sEURO|\sCONTANTI|\sECT.]

无论如何,这会给你一个想法。修改它,直到你让它按照你想要的方式工作。

$testo2 = "Del burger Sr Via Carlo del Prete 106/d 50127 FIRENZE C.F. E P.IVA 08380120482 BRUNCH MAMMAMIA ONION RINGS SPICCHI PATATE ACQUA 0.5L TAVOLO 88 EURO 6,50 6,50 4,00 3,00 1,00 TOTALE EURO CONTANTI 21,00 21,00 NR.0057 23/05/18 20:21 MF U1 72005985";
$testo2 = preg_replace('/\s{1,}/', ' ', $testo2);
preg_match('/[\s\S]{0,}TOTALE\s[\sEURO|\sCONTANTI]{0,}\s(.*?)\s/', $testo2, $match);

echo $match[1];  //<--- Outputs "21,00"

第二种解法

我相信您可以疯狂使用正则表达式并使某些东西起作用,但我们需要多个示例来借鉴。一个更好的主意可能是假设总金额始终是收据上的最高金额。如果是这样的话,我们可以这样做:

function getReceiptTotal($receipt){

  preg_match_all('/\d+[\.,]\d+\s/', $receipt, $match);

  $comma = preg_match('/,/', $match[0][0]) ? TRUE : FALSE;

  for($i = 0; $i < count($match[0]); $i++){

    $match[0][$i] = trim($match[0][$i]);

    if($comma){

      $temp[] = preg_replace('/,/', '.', $match[0][$i]);

    } 

  }

  sort($temp);

  $total = end($temp);

  if($comma){

    return preg_replace('/\./', ',', $total);


  } else {

    return $total;

    }

}

echo getReceiptTotal($testo2); //Will output "21,00".

这应该适用于您所有的收据类型。

要找到总数,您可以使用 preg_match

TOTALE EURO CONTANTI\s*\K\d+[.,]\d+

或者在 TOTALE EURO CONTANTI 之间有一个或多个空白字符:

TOTALE\s+EURO\s+CONTANTI\s+\K\d+[.,]\d+

您可以匹配 TOTALE EURO CONTANTI 后跟零个或多个空白字符,\s* 然后重置匹配的起点。然后使用字符 class 后跟一个或多个数字 \d+[.,]\d+

来匹配一个或多个数字、逗号或点
$re = '/TOTALE EURO CONTANTI\s*\K\d+,\d+/';
$str = 'Del burger Sr Via Carlo del Prete 106/d 50127 FIRENZE C.F. E P.IVA 08380120482 BRUNCH MAMMAMIA ONION RINGS SPICCHI PATATE ACQUA 0.5L TAVOLO 88 EURO 6,50 6,50 4,00 3,00 1,00 TOTALE EURO CONTANTI 21,00 21,00 NR.0057 23/05/18 20:21 MF U1 72005985';

preg_match($re, $str, $matches);
echo $matches[0]; // 21,00

Demo