За последние 24 часа нас посетили 17274 программиста и 1226 роботов. Сейчас ищет 1491 программист ...

год, года, лет

Тема в разделе "Регулярные выражения", создана пользователем _AVS_, 24 ноя 2007.

  1. _AVS_

    _AVS_ Активный пользователь

    С нами с:
    20 сен 2007
    Сообщения:
    46
    Симпатии:
    0
    Здравствуйте!

    У меня такая задача. В зависимости от числа, к нему подставляется одно из слов: год, года, лет. Например, 1 год, 2 года, 12 лет и так к любому числу.

    Для проверочки организовал все это в цикле. Но вот что-то составить корректное регулярное выражение не могу, хотя вроде задача не сложная. Некоторые числа комментирует некорректно.

    PHP:
    1.  
    2. for($i=1;$i<=200;$i++)
    3. {
    4.     if(preg_match("/[02-9]?(1)+$/",$i) && !preg_match("|(11)$|",$i))
    5.     {
    6.         $comment='год';
    7.     }
    8.     elseif(preg_match("/[\d]?(2|3|4)+$/",$i))
    9.         {
    10.             $comment='года';
    11.         }
    12.         else
    13.         {
    14.             $comment='лет';
    15.         }
    16.         echo $i.' '.$comment.'<br>';
    17. }
    18.  
     
  2. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    В русском языке существует три варианта окончания для чисел. Закономерность:
    если число заканчивается заканчивается на 1, то одна форма;
    если на 2, 3 или 4, то другая;
    в противном случае - третья.
    Исключение составляют числа 11, 12, 13 и 14: они всегда имеют третью форму окончания (или слова целиком).


    PHP:
    1. <?php
    2.  
    3. function ending($num, $first, $second, $third) {
    4.     $num = (int)$num;
    5.    
    6.     if ($num < 21 && $num > 4)
    7.         return $third;
    8.  
    9.     $num = $num%10;
    10.  
    11.     if ($num == 1)
    12.         return $first;
    13.     if ($num > 1 && $num < 5)
    14.         return $second;
    15.  
    16.     return $third;
    17. }
    18.  
    19.  
    20. ?>
     
  3. S.t.A.M.

    S.t.A.M. Активный пользователь

    С нами с:
    10 сен 2007
    Сообщения:
    1.041
    Симпатии:
    0
    Ну и мой вариант:
    PHP:
    1.  
    2. <?php
    3. for($i=1;$i<=200;$i++)
    4. {
    5.     echo yaer_format($i)."<br>";
    6. }
    7.  
    8. function yaer_format($i)
    9. {
    10.     ereg("..$",$i,$t);
    11.     $s=$t[0];
    12.     if ($s>=5 && $s<=20)
    13.         {
    14.             $res = $i." лет";
    15.         } else
    16.         {
    17.             ereg(".$",$i,$t);
    18.             $s=$t[0];
    19.             if ($s=="1") {$res = $i." год";}
    20.             elseif (in_array($s,Array("2","3","4"))) {$res = $i." года";}  
    21.             else {$res = $i." лет";}    
    22.         }
    23.     return $res;
    24. }
    25. ?>
     
  4. S.t.A.M.

    S.t.A.M. Активный пользователь

    С нами с:
    10 сен 2007
    Сообщения:
    1.041
    Симпатии:
    0
    А также 111, 112, 113 и 114, 211, 212, 213 и 214 и т.д.
     
  5. _AVS_

    _AVS_ Активный пользователь

    С нами с:
    20 сен 2007
    Сообщения:
    46
    Симпатии:
    0
    Реализовал вот так. Работает правильно.

    PHP:
    1.  
    2. <?php
    3. for($i=1;$i<=200;$i++)
    4. {
    5.     // Если число заканчивается на 1
    6.     if(preg_match("|(1)$|",$i))
    7.     {
    8.         $comment='год';
    9.     }   // Если число заканчивается на 2,3,4
    10.     elseif(preg_match("/(2|3|4)$/",$i))
    11.         {
    12.             $comment='года';
    13.         }
    14.         else
    15.         {
    16.             $comment='лет';
    17.         }
    18.    
    19.     // Если заканчивается на 10-19
    20.     if(preg_match("/(1)[0-9]$/",$i))
    21.     {
    22.         $comment='лет';
    23.     }
    24.    
    25.     echo $i.' '.$comment.'<br>';
    26. }
    27. ?>
    28.  
     
  6. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Точно! :)
    Этой функции уже несколько лет, а никто почему-то не жаловался :)
     
  7. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Тогда так:

    PHP:
    1. <?php
    2.  
    3. function ending($num, $first, $second, $third) {
    4.     $num = $num%100;
    5.    
    6.     if ($num < 21 && $num > 4)
    7.         return $third;
    8.  
    9.     $num = $num%10;
    10.  
    11.     if ($num == 1)
    12.         return $first;
    13.     if ($num > 1 && $num < 5)
    14.         return $second;
    15.  
    16.     return $third;
    17. }
    18.  
    19.  
    20. ?>
     
  8. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    PHP:
    1. <?php
    2. function _decl( $numb, $one, $double, $multy ){
    3.     $d1= $numb % 10;
    4.     $d2= ( $numb / 10 ) % 10;
    5.     if( $d2 != 1 ){
    6.         if(( $d1 > 1 )&&( $d1 < 5 )) return $double;
    7.         if( $d1 == 1 ) return $one;
    8.     }
    9.     return $multy;
    10. }
    11. ?>
     
  9. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Немного не то 8) Но вариант, который недавно написал для используемых случаев на странице.
    PHP:
    1. <?php
    2. function ender($slovo, $number, $type) {
    3.     //Типы: сингл - 1 тип (сингл, синглов, сингла), композиц -2 тип (композиция/ии/ий)
    4.     $types = array (1 => array ('', 'а', 'ов'), 2 => array('ия', 'ии', 'ий'));
    5.     $number = (int)$number;
    6.     $sub1 = substr($number, -1);
    7.     $sub2 = substr($number, -2);
    8.     if ($sub1  == 1 and $sub2 != 11) {
    9.         return $slovo.$types[$type][0];
    10.     }
    11.     elseif (($sub1== 2 or $sub1== 3 or $sub1== 4) && ($sub2 != 12 and $sub2 != 13 and $sub2 != 14)) {
    12.         return $slovo.$types[$type][1];
    13.     }
    14.     else {
    15.         return $slovo.$types[$type][2];
    16.     }
    17. }
    18. ?>
     
  10. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
  11. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    PHP:
    1.  
    2. <?
    3. # склоняем по падежам
    4. function OOPSSpell($num, $base, $endings) {
    5.     if ($num % 100 >= 11 && $num % 100 <= 19) {
    6.         return $base . $endings[2];
    7.     } else {
    8.         switch ($num % 10) {
    9.           case 1:
    10.           return $base . $endings[0];
    11.           case 2: case 3: case 4:
    12.           return $base . $endings[1];
    13.           default:
    14.           return $base . $endings[2];
    15.         }
    16.      }
    17. }
    18. ?>
    19.  
    PHP:
    1.  
    2. <?
    3. print OOPSSpell(42,'жоп',array('а','ы',''));
    4. ?>
     
  12. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Разве это падежи? :)
     
  13. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    Kreker

    не. это числительные.
    =)

    это я просто такой неграмотный...

    а по падежам надо по другому склонять