BG Development


  Reply to this topicStart new topicStart Poll

> Превръщане на числа в думи, PHP
cpuin
Публикувано на: 05-01-2017, 21:58
Quote Post



Име:
Група: Потребител
Ранг: Старо куче

Мнения: 859
Регистриран на: 06.03.12



Здравейте,

Използвам готов скрипт за превръшане от числа в думи и суми..
Работи си ок с "малко" изключение.Когато сумата е с хиляди и се появи разделителна запетайка, започва да я счита за цяло и така например при

4,040.90 връща
четири лева и 04 ст.

Не мога да разбера, според мен в началото на кода str_replace(',','.',"$number") изчиства запетайките, но не мога да разбра от къде е, а и по regular expression са ми мътни малко.....


CODE

function convert_number_to_words_bg($number) {
$number=str_replace(',','.',"$number");
$number=@money_format('%.2n',$number);
$number=explode('.',$number);
if (!empty($number[1])) $decimals=$number[1]; else $decimals=0;
$number=$number[0];
$char_count=strlen($number);
$pos=array();
for ($i=1;$i<=$char_count;$i++) {
if ($i<=3) {
$pos[1]=substr($number,-$i,1).$pos[1];
}
if ($i<=6 AND $i>3) {
$pos[2]=substr($number,-$i,1).$pos[2];
}
if ($i<=9 AND $i>6) {
$pos[3]=substr($number,-$i,1).$pos[3];
}
}
for ($k=1;$k<=3;$k++) {
for ($i=1;$i<=strlen($pos[$k]);$i++) {
$cur=substr($pos[$k],-$i,1);
unset($temp);
if ($i==3) {
switch($cur) {
case 1: $temp='сто'; break;
case 2: $temp='двеста'; break;
case 3: $temp='триста'; break;
case 4: $temp='четиристотин'; break;
case 5: $temp='петстотин'; break;
case 6: $temp='шестстотин'; break;
case 7: $temp='седемстотин'; break;
case 8: $temp='осемстотин'; break;
case 9: $temp='деветстотин'; break;
}
$pos_hunds[$k]=$temp;
}
if ($i==2) {
switch($cur) {
case 2: $temp='двадесет'; break;
case 3: $temp='тридесет'; break;
case 4: $temp='четиридесет'; break;
case 5: $temp='петдесет'; break;
case 6: $temp='шестдесет'; break;
case 7: $temp='седемдесет'; break;
case 8: $temp='осемдесет'; break;
case 9: $temp='деветдесет'; break;
}
$pos_decs[$k]=$temp;
}
if ($i==1) {
switch($cur) {
case 1: $temp='ед'; break;
case 2: $temp='дв'; break;
case 3: $temp='три'; break;
case 4: $temp='четири'; break;
case 5: $temp='пет'; break;
case 6: $temp='шест'; break;
case 7: $temp='седем'; break;
case 8: $temp='осем'; break;
case 9: $temp='девет'; break;
}
if($pos[$k]>9 AND substr($pos[$k],-2,1)==1) {
if($temp=='ед') $temp=$temp."и";
if($temp=='дв') $temp=$temp."а";
if(substr($pos[$k],-2,1)==1 AND substr($pos[$k],-1,1)==0) $temp='десет';
else $temp=$temp."надесет";
}
if(substr($pos[$k],-2,1)!==1 AND $k!==2) {
if($temp=='ед') $temp=$temp."ин";
if($temp=='дв') $temp=$temp."а";
}
if($k==2) {
if($temp=='ед') $temp=$temp."на";
if($temp=='дв') $temp=$temp."е";
if($pos[$k]==1) $temp='хиляда';
}
$pos_sings[$k]=$temp;
}
}
}
unset($read);
for ($i=1;$i<=3;$i++) {
if (!empty($pos_hunds[$i]) AND !empty($pos_decs[$i]) AND !empty($pos_sings[$i])) $read[$i]=$pos_hunds[$i]." ".$pos_decs[$i]." и ".$pos_sings[$i];
if (!empty($pos_hunds[$i]) AND !empty($pos_decs[$i]) AND empty($pos_sings[$i])) $read[$i]=$pos_hunds[$i]." и ".$pos_decs[$i];
if (!empty($pos_hunds[$i]) AND empty($pos_decs[$i]) AND empty($pos_sings[$i])) $read[$i]=$pos_hunds[$i];
if (!empty($pos_hunds[$i]) AND empty($pos_decs[$i]) AND !empty($pos_sings[$i])) $read[$i]=$pos_hunds[$i]." и ".$pos_sings[$i];;
if (empty($pos_hunds[$i]) AND !empty($pos_decs[$i]) AND !empty($pos_sings[$i])) $read[$i]=$pos_decs[$i]." и ".$pos_sings[$i];
if (empty($pos_hunds[$i]) AND !empty($pos_decs[$i]) AND empty($pos_sings[$i])) $read[$i]=$pos_decs[$i];
if (empty($pos_hunds[$i]) AND empty($pos_decs[$i]) AND !empty($pos_sings[$i])) $read[$i]=$pos_sings[$i];
if (empty($pos_hunds[$i]) AND empty($pos_decs[$i]) AND empty($pos_sings[$i])) $read[$i]='';
switch($i) {
case 1: if ($pos[1]>1 OR $pos[2]>0 OR $pos[3]>0) $read[$i]=$read[$i]." лева"; else $read[$i]=$read[$i]." лев";break;
case 2: if($pos[2]>1) $read[$i]=$read[$i]." хиляди";break;
case 3: if ($pos[3]>1) $read[$i]=$read[$i]." милиона"; else if(!empty($pos[3])) $read[$i]=$read[$i]." милион";break;
}
}
if ($pos[1]=='000') $pos[1]=0;
if ($pos[2]=='000') $pos[2]=0;
if (!empty($pos[3]) AND !empty($pos[2]) AND !empty($pos[1]) AND substr($pos[1],-2,2)==0) $ready=$read[3]." ".$read[2]." и ".$read[1];
if (!empty($pos[3]) AND !empty($pos[2]) AND !empty($pos[1]) AND substr($pos[1],-2,2)>0) $ready=$read[3]." ".$read[2]." ".$read[1];
if (!empty($pos[3]) AND !empty($pos[2]) AND empty($pos[1]) AND substr($pos[2],-2,2)==0) $ready=$read[3]." и ".$read[2];
if (!empty($pos[3]) AND !empty($pos[2]) AND empty($pos[1]) AND substr($pos[2],-2,2)>0) $ready=$read[3]." ".$read[2];
if (!empty($pos[3]) AND empty($pos[2]) AND !empty($pos[1]) AND substr($pos[1],-2,2)==0) $ready=$read[3]." и ".$read[1];
if (!empty($pos[3]) AND empty($pos[2]) AND !empty($pos[1]) AND substr($pos[1],-2,2)>0) $ready=$read[3]." ".$read[1];
if (!empty($pos[3]) AND empty($pos[2]) AND empty($pos[1])) $ready=$read[3];
if (empty($pos[3]) AND !empty($pos[2]) AND !empty($pos[1]) AND substr($pos[1],-2,2)==0) $ready=$read[2]." и ".$read[1];
if (empty($pos[3]) AND !empty($pos[2]) AND !empty($pos[1]) AND substr($pos[1],-2,2)>0) $ready=$read[2]." ".$read[1];
if (empty($pos[3]) AND !empty($pos[2]) AND empty($pos[1])) $ready=$read[2];
if (empty($pos[3]) AND empty($pos[2]) AND !empty($pos[1])) $ready=$read[1];
if (empty($pos[3]) AND empty($pos[2]) AND empty($pos[1])) $ready='';
if (empty($pos[1])) $ready=$ready." лева";
$ready=$ready." и $decimals ст.";
if (!empty($pos[1]) OR !empty($pos[2]) OR !empty($pos[3])) return $ready;
}



//THIS FUNCYION CONVERT URL STRINGS FROM CYRLIC AND OTHER LANGUAGES IN READABLE, I USE IT IN PRODUCTS/SEARCH
function unescape($str){
$ret = '';
$len = strlen($str);
for ($i = 0; $i < $len; $i++){
if ($str[$i] == '%' && $str[$i+1] == 'u'){
$val = hexdec(substr($str, $i+2, 4));
if ($val < 0x7f) $ret .= chr($val);
else if($val < 0x800) $ret .= chr(0xc0|($val>>6)).chr(0x80|($val&0x3f));
else $ret .= chr(0xe0|($val>>12)).chr(0x80|(($val>>6)&0x3f)).chr(0x80|($val&0x3f));
$i += 5;
}
else if ($str[$i] == '%'){
$ret .= urldecode(substr($str, $i, 3));
$i += 2;
}
else $ret .= $str[$i];
}
return $ret;
}


--------------------
"Трудните неща изискват време, невъзможните - просто малко повече"
PMEmail Poster
Top
TrustHavic
Публикувано на: 05-01-2017, 23:13
Quote Post



Име: Станимир
Група: Потребител
Ранг: Активен

Мнения: 272
Регистриран на: 30.04.14



PMEmail Poster
Top
soNewbie
Публикувано на: 06-01-2017, 09:56
Quote Post



Име:
Група: Потребител
Ранг: Новопостъпил

Мнения: 16
Регистриран на: 03.12.16



QUOTE (cpuin @ 05-01-2017, 21:58)
Не мога да разбера, според мен в началото на кода str_replace(',','.',"$number") изчиства запетайките, но не мога да разбра от къде е, а и по regular expression са ми мътни малко.....


http://php.net/manual/bg/function.str-replace.php
Не ти зачиства а ти ги замества с точка и става 4.040.90
и от там вече се обърква, ако го заместиш с празно '', ще ти изведе правилно

http://codepad.org/CjdXRDya

Това мнение е било редактирано от soNewbie на 06-01-2017, 10:56
PM
Top
Антон Яначков
Публикувано на: 06-01-2017, 19:08
Quote Post



Име: Антон Яначков
Група: Потребител
Ранг: Посетител

Мнения: 148
Регистриран на: 27.07.16



Редът който замества запетайката с точка има за идея да направи скрипта по-дуракоустойчив. В смисъл ако въведеш 4,90 той да го подмени с 4.90 и всичко да е точно. Но ако въведеното число съдържа и запетайка и точка, в този случай в числото изведнъж се появяват две точки.
Ето защо трябва да усъвършенстваш дуракоустойчивостта на скрипта. Ако в зададеното число се съдържат и запетайка и точка, то заместваме запетайката с нищо, но ако се съдържа само запетайка то в този случай заместваме запетайката с точка, както е при теб и пак няма да е достатъчно дуракоустойчиво, защото някой може да иска да въведе разделител запетайка за хиляди, а десетична точка изобщо да няма и скрипта отново ще сбърка, защото ще подмени запетайката с точка и тотално ще промени числото. Тоест трябва ти компромис, с който да се примириш. Може би трябва твърдо да забраниш на потребителя да въвежда запетайки или точки по твой избор. Имай предвид, че в българския език фигурира десетична запетая и за това в училищата децата работят с разделител запетая.
PMEmail PosterUsers Website
Top
ivan84
Публикувано на: 07-01-2017, 06:22
Quote Post



Име:
Група: Форумен член
Ранг: Почетен член

Мнения: 8170
Регистриран на: 01.04.11



Здрасти хакер, как е? Какво стана с първия закон на програмирането в който искрено вярваше?
Решението на "проблема" е съвсем тривиално - махат се всички сепаратори освен последния...
PMEmail Poster
Top
georgib1
Публикувано на: 07-01-2017, 09:50
Quote Post



Име:
Група: Потребител
Ранг: Старо куче

Мнения: 881
Регистриран на: 26.09.16



Добре де, не съм запознат дали става така в php, но - когато се въведе нещо в символния низ, пускаш един масив и правиш проверка, ако е число го променяш на буквата, която искаш.Например, 5- А, 6-Б.Не знам дали имаш предвид това. icon_lol.gif
PMEmail Poster
Top
Антон Яначков
Публикувано на: 11-01-2017, 11:22
Quote Post



Име: Антон Яначков
Група: Потребител
Ранг: Посетител

Мнения: 148
Регистриран на: 27.07.16



QUOTE (ivan84 @ 07-01-2017, 06:22)
Какво стана с първия закон на програмирането в който искрено вярваше?
Решението на "проблема" е съвсем тривиално - махат се всички сепаратори освен последния...

Като махнеш всички сепаратори и оставиш само последния, какво ще стане ако няма дробна част. Изведнъж ще се появи и ще се окаже, че си я втасал здраво.
Пример:
40,190.40 ще ти даде верен резултата, но 40,190 ще те метне в тиквити, защото последния сепаратор си го оставил и ще сгрешиш само с 3 порядъка.

Лично аз още при въвеждането на числото бих контролирал точките и запетайките. Ако съм решил, че ще използвам запетайка то при въвеждане на точка бих предупредил клиента, ако се опита да въведе две запетайки отново бих го предупредил.

А относно първия закон той винаги е в сила, независимо от твоето отношение към него.
PMEmail PosterUsers Website
Top
1 потребители преглеждат тази тема в момента (1 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2015 | BG Development | All Rights Reserved
RSS 2.0