|
|
|
| Всем привет!
Пожалуйста, помогите с задачкой. Необходимо взять целое число из разных форматов его представления, например:
из цены 23 745.00руб. нужно получить целое число 23745, и так далее
23 745.10руб. = 23745
23 745,10руб. = 23745
23 745.20 = 23745
23 745.30. = 23745
23 745,5руб. = 23745
23.745,00руб. = 23745
23,745.0руб. = 23745
23, 745.00руб. = 23745
Поискал на форуме, кажется таких вопросов и решений еще не было, заранее, огромное спасибо! | |
|
|
|
|
|
|
|
для: jq
(11.09.2013 в 16:32)
| | Можно отталкиваться от следующего скрипта
<?php
$arr[] = "23 745.10руб.";
$arr[] = "23 745,10руб.";
$arr[] = "23 745.20";
$arr[] = "23 745.30.";
$arr[] = "23 745,5руб.";
$arr[] = "23.745,00руб.";
$arr[] = "23,745.0руб.";
$arr[] = "23, 745.00руб.";
for($i = 0; $i < count($arr); $i++){
$arr[$i] = rtrim(preg_replace("/[^\d,\.]+/", "", $arr[$i]), ".,");
$arr[$i] = preg_replace("/[,.]\d+$/", "", $arr[$i]);
$arr[$i] = preg_replace("/[^\d]+/", "", $arr[$i]);
}
echo "<pre>"; print_r($arr); echo "</pre>";
?>
|
| |
|
|
|
|
|
|
|
для: cheops
(13.09.2013 в 21:47)
| | А к чему такие "навороты???
/\b(\d+?)([\., ])(\d+?)(?:[\.,])(\d+(руб)?(\.)?)/
|
Вот пример: http://jsbin.com/EjIzEgo/2/edit?js,output | |
|
|
|
|
|
|
|
для: Deed
(14.09.2013 в 14:25)
| | Если уж говорить "а не лучше?", то нужно удалить первый не цифровой символ в строке и преобразовать полученное в integer. | |
|
|
|
|
|
|
|
для: confirm
(14.09.2013 в 14:55)
| | Ну и? http://jsbin.com/UWiZubA/1/edit?html,js,output
Даже если убрать все не цифровые символы, то как потом быть с отсечением дробной части, которая отделяется от целого ИЛИ точкой, ИЛИ запятой?
Тем более, "регулярка" - универсальнее, не так ли? | |
|
|
|
|
|
|
|
для: Deed
(14.09.2013 в 15:15)
| | Вы прежде чем задавать вопросы, выполнили бы:
<?
echo (int)'23745.10руб'; //23745
|
| |
|
|
|
|
|
|
|
для: confirm
(14.09.2013 в 15:19)
| |
<?
echo (int)'23 745.10руб'; //23
echo (int)'23,745.0руб.'; //23
echo (int)'23.745,00руб.'; //23
?>
|
Нормально... Тем более, все равно необходимы промежуточные операции.
Да и тема посвящена регулярным выражениям. | |
|
|
|
|
|
|
|
для: Deed
(14.09.2013 в 16:16)
| | Вы русский язык учили? А я ведь писал на русском - удалить первый не цифровой символ, и ...
Нет в программировании задач посвященных рег. выражениям, циклам не циклам, и тому подобному, задачи решаются с учетом выгоды. И если говорить о вашей навороченной строке, то она отличается только наворотами, более ни чем, и то что предложили ранее, выполнит задачу и побыстрее ваших наворотов. Если уж на то пошло. | |
|
|
|
|
829 байт |
|
|
для: confirm
(14.09.2013 в 16:24)
| | Ну... Не ожидал я такого от вас.
Никак не ожидал.
Первый вариант (причем БЕЗ разбиения исходной строки на фрагменты!):
<?php
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$time_start = getmicrotime();
$arr[] = "23 745.10руб.";
$arr[] = "23 745,10руб.";
$arr[] = "23 745.20";
$arr[] = "23 745.30.";
$arr[] = "23 745,5руб.";
$arr[] = "23.745,00руб.";
$arr[] = "23,745.0руб.";
$arr[] = "23, 745.00руб.";
for($i = 0; $i < count($arr); $i++){
$arr[$i] = rtrim(preg_replace("/[^\d,\.]+/", "", $arr[$i]), ".,");
$arr[$i] = preg_replace("/[,.]\d+$/", "", $arr[$i]);
$arr[$i] = preg_replace("/[^\d]+/", "", $arr[$i]);
}
$time_end = getmicrotime();
$time = $time_end - $time_start;
echo "Did nothing in $time seconds";
?>
|
Дает время: 0.00029301643371582 seconds.
Второй вариант (с одной-единственной регуляркой!):
<?php
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$time_start = getmicrotime();
$str="
23 745.10руб. = 23745
23 745,10руб. = 23745
23 745.20 = 23745
23 745.30. = 23745
23 745,5руб. = 23745
23.745,00руб. = 23745
23,745.0руб. = 23745
23, 745.00руб. = 23745
";
$str2=preg_replace("/\b(\d+?)([\., ])(\d+?)(?:[\.,])(\d+(руб)?(\.)?)/us","$1$3",$str);
$time_end = getmicrotime();
$time = $time_end - $time_start;
echo "Did nothing in $time seconds";
?>
|
Показывает время выполнения: 0.00010991096496582 seconds, то есть, на 37,5% быстрее.
Можете проверить.
Подчеркиваю, если в первый вариант (first_var.php в архиве) добавить разбиение исходной строки для последующего заполнения массива, разница во времени значительно возрастет. | |
|
|
|
|
|
|
|
для: Deed
(14.09.2013 в 17:00)
| | Вы рано радуетесь, это не тот пример на котором выгоду сравнивать. И поправьте свой шаблон, сдается он не во всем подходит.
И вообще, чтобы закрыть этот разговор:
<?
$start = microtime(true); //надобности в функции для этого нет никакой
$arr = array("23 745.10руб.", "23 745,10руб.", "23 745.20", "23 745.30.",
"23 745,5руб.", "23.745,00руб.", "23,745.0руб.", "23, 745.00руб.");
while($n = array_shift($arr)) echo (int)preg_replace("/\D+(?=\d{3})/", "", $n).'<br>';
echo '<br>' . $start .'<br>'. microtime(true);
|
И на калькуляторе считайте, если конечно есть что. | |
|
|
|
|
676 байт |
|
|
для: confirm
(14.09.2013 в 17:57)
| | А, да: \b(\d+?)([\., ]+)(\d+?)(?:[\.,])(\d+(руб)?(\.)?)
Выполните скрипт:
<?php
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$time_start = getmicrotime();
$str="
23 745.10руб. = 23745
23 745,10руб. = 23745
23 745.20 = 23745
23 745.30. = 23745
23 745,5руб. = 23745
23.745,00руб. = 23745
23,745.0руб. = 23745
23, 745.00руб. = 23745
";
$str2=preg_replace("/\b(\d+?)([\., ]+)(\d+?)(?:[\.,])(\d+(руб)?(\.)?)/us","<br>$1$3",$str);
$time_end=getmicrotime();
$res=$time_end-$time_start;
echo $str2."<br>My result is ".$res."<br>";
//====================//
$start = getmicrotime(); //C функцией нагляднее!
$arr = array("23 745.10руб.", "23 745,10руб.", "23 745.20", "23 745.30.",
"23 745,5руб.", "23.745,00руб.", "23,745.0руб.", "23, 745.00руб.");
while($n = array_shift($arr)) echo (int)preg_replace("/\D+(?=\d{3})/", "", $n).'<br>';
$end=getmicrotime();
$res2=$end-$start;
echo '<br>Your result is '.$res2.'<br><br>';
$faster=$res*100/$res2;
echo "the first variant is faster than the second at ".$faster."%";
?>
|
И воочию убедитесь, что первый вариант быстрее второго в среднем на 60%
И это с учетом того, что во втором варианте строку нужно еще разбить на фрагменты. | |
|
|
|
|
|
|
|
для: Deed
(15.09.2013 в 03:36)
| | Вот неугомонный.
1. Функция ни к чему потому, что время исполнения настолько мизерное, что вытягивать из возвращенного microtim секунды нет смысла. Вы просто вытянули эту функцию из примера руководства и все, а не вдомек, что нужно всего лишь array_shift(explode(' ', microtime())), или explode(' ', microtime(), -1) для вычисления.
2. То что я написал, может показывать время исполнения от A до Z, в котором есть и ваши 0.0001... и меньшие значения, и большие. О чем это говорит? А ни о чем. В моем случае, кроме разбора компьютер выполняет и другие задачи. Хотите разобрать сколько и на что? Тогда используйте тики.
3. Ну и главное, это вы загнали все в строку, хотя скорее всего на самом деле нет ни ее, ни массива, а есть одно поступающее на вход значение, которое может представлять из себя один из показанных вариантов. Вот по единичному значению и нужно проводить сравнение. Но и в этом случае microtime покажет время общее, а не то, как приходится парсеру трудится над вашим шаблоном.
4. При действительно больших разборах попробуйте разбить разбор на части, или нагрузить сразу.
5. Ваш шаблон заставляет учитывать лишнее (us) - цифра, точка, запятая не знают что такое utf, а для "руб", не нужно (см. 3), если представлять решение не в лоб.
6. В данном разделе много вопросов, которые к рег. выражениям вообще отношения не имеют, то есть, решить их можно вообще без применения PCRE. Одним словом, лучше заниматься не подсчетом времени на вариации, а искать решения не прожорливые. | |
|
|
|
|
|
|
|
для: confirm
(15.09.2013 в 09:54)
| | Ну да, естественно. Предположение, что на обработку подается лишь один вариант строки из предложенных, меняет все. И приведение к целому работает более, чем в два раза быстрее.
P.S. Красивое решение! | |
|
|
|
|