Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Регулярные Выражения

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Взять целое число
 
 автор: jq   (11.09.2013 в 16:32)   письмо автору
 
 

Всем привет!

Пожалуйста, помогите с задачкой. Необходимо взять целое число из разных форматов его представления, например:

из цены 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

Поискал на форуме, кажется таких вопросов и решений еще не было, заранее, огромное спасибо!

  Ответить  
 
 автор: cheops   (13.09.2013 в 21:47)   письмо автору
 
   для: 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>";
?>

  Ответить  
 
 автор: Deed   (14.09.2013 в 14:25)   письмо автору
 
   для: cheops   (13.09.2013 в 21:47)
 

А к чему такие "навороты???
/\b(\d+?)([\., ])(\d+?)(?:[\.,])(\d+(руб)?(\.)?)/

Вот пример: http://jsbin.com/EjIzEgo/2/edit?js,output

  Ответить  
 
 автор: confirm   (14.09.2013 в 14:55)   письмо автору
 
   для: Deed   (14.09.2013 в 14:25)
 

Если уж говорить "а не лучше?", то нужно удалить первый не цифровой символ в строке и преобразовать полученное в integer.

  Ответить  
 
 автор: Deed   (14.09.2013 в 15:15)   письмо автору
 
   для: confirm   (14.09.2013 в 14:55)
 

Ну и? http://jsbin.com/UWiZubA/1/edit?html,js,output
Даже если убрать все не цифровые символы, то как потом быть с отсечением дробной части, которая отделяется от целого ИЛИ точкой, ИЛИ запятой?
Тем более, "регулярка" - универсальнее, не так ли?

  Ответить  
 
 автор: confirm   (14.09.2013 в 15:19)   письмо автору
 
   для: Deed   (14.09.2013 в 15:15)
 

Вы прежде чем задавать вопросы, выполнили бы:
<?
echo (int)'23745.10руб'//23745

  Ответить  
 
 автор: Deed   (14.09.2013 в 16:16)   письмо автору
 
   для: confirm   (14.09.2013 в 15:19)
 


<?
echo (int)'23 745.10руб'//23

echo (int)'23,745.0руб.'//23

echo (int)'23.745,00руб.'//23

?>

Нормально... Тем более, все равно необходимы промежуточные операции.
Да и тема посвящена регулярным выражениям.

  Ответить  
 
 автор: confirm   (14.09.2013 в 16:24)   письмо автору
 
   для: Deed   (14.09.2013 в 16:16)
 

Вы русский язык учили? А я ведь писал на русском - удалить первый не цифровой символ, и ...

Нет в программировании задач посвященных рег. выражениям, циклам не циклам, и тому подобному, задачи решаются с учетом выгоды. И если говорить о вашей навороченной строке, то она отличается только наворотами, более ни чем, и то что предложили ранее, выполнит задачу и побыстрее ваших наворотов. Если уж на то пошло.

  Ответить  
 
 автор: Deed   (14.09.2013 в 17:00)   письмо автору
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 в архиве) добавить разбиение исходной строки для последующего заполнения массива, разница во времени значительно возрастет.

  Ответить  
 
 автор: confirm   (14.09.2013 в 17:57)   письмо автору
 
   для: 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);

И на калькуляторе считайте, если конечно есть что.

  Ответить  
 
 автор: Deed   (15.09.2013 в 03:36)   письмо автору
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%
И это с учетом того, что во втором варианте строку нужно еще разбить на фрагменты.

  Ответить  
 
 автор: confirm   (15.09.2013 в 09:54)   письмо автору
 
   для: 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. Одним словом, лучше заниматься не подсчетом времени на вариации, а искать решения не прожорливые.

  Ответить  
 
 автор: Deed   (15.09.2013 в 11:13)   письмо автору
 
   для: confirm   (15.09.2013 в 09:54)
 

Ну да, естественно. Предположение, что на обработку подается лишь один вариант строки из предложенных, меняет все. И приведение к целому работает более, чем в два раза быстрее.

P.S. Красивое решение!

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования