Foren / National / Russian / Зоопарк с окончаниями

ErsteVorherige1234567NächsteLetzte

Sergey
#46 9. Februar 2009, 23:17
Ratibor:
С пальто это было тонкая шутка о склонениях - вы ее не поняли и не так оценили. Я просто показал, что исключений куда как больше, чем правил, есть еще и отрицательные числа и дробные (но тут уже чересчур)
while($mydigit>20) {$mydigit=$mydigit%10;} доводим все до 20 вариантов
0 файлов if($mydigit == 0) {return ($ew[0].$ew[1]);}
1 файл if($mydigit == 1) {return ($ew[0].$ew[2]);}
2 файла if($mydigit >= 2 && $mydigit <= 4 ) {return ($ew[0].$ew[3]);}
3 файла
4 файла
5 файлов if($mydigit >= 5 && $mydigit <= 20 ) {return ($ew[0].$ew[4]);}
6 файлов
7 файлов
8 файлов
9 файлов
10 файлов
11 файлов
12 файлов
13 файлов
14 файлов
15 файлов
16 файлов
17 файлов
18 файлов
19 файлов
20 файлов == 120 файлов
21 файл == 1 файл = 121 файл == 1021 файл
22 файла == 2 файла =122 файла == 1000022 файла
Но мне все-равно какой вариант, главное чтобы работал
www.cotonti.mobi
Ratibor
#47 9. Februar 2009, 23:29
# Sergey : Я просто показал, что исключений куда как больше, чем правил, есть еще и отрицательные числа и дробные (но тут уже чересчур)
Еще раз повторяю вопрос, назови хотябы один пример с которым мой вариант не справится ?
Не задавай глупых вопросов, не услышишь вранья.
Sergey
#48 9. Februar 2009, 23:38
Ratibor! если можно, оформите отдельным тестовым файлом, чтобы я и другие (хотя бы для русского) могли бы протестировать автономно без напряжений мыслей, хорошо. А то как понимаете, тяжеловато мысли бегуются вместо электронов в процессоре.
www.cotonti.mobi
dervan
#49 9. Februar 2009, 23:47
# Sergey : ... есть еще и отрицательные числа и дробные (но тут уже чересчур)
С отрицательными числами работать будет, минусы поест preg_replace():
$i=preg_replace('/[^0-9]+/s','',$digit)%100; //intval не всегда корректно работает

А дробные - даже не знаю зачем это, тоже думаю что чересчур. :) Вряд ли функцища declension() будет применяться для дробных чисел. Для отрицательных - и то маловероятно.
Ratibor
#50 10. Februar 2009, 00:19
# Sergey : Ratibor! если можно, оформите отдельным тестовым файлом, чтобы я и другие (хотя бы для русского) могли бы протестировать автономно без напряжений мыслей, хорошо.
А все уже давно оформлено, скачивай с транка последнюю ревизию и тестируй на здоровье.

dervan
как избавиться вот от этого:

    switch ($plural) {
        case 0:
            $res=$digit.' '.$expr[0];
            break;
        case 1:
            $res=$digit.' '.$expr[1];
            break;
        case 2:
            $res=$digit.' '.$expr[2];
            break;
        case 3:
            $res=$digit.' '.$expr[3];
            break;
        case 4:
            $res=$digit.' '.$expr[4];
            break;
 
            default: $res=$digit.' '.$expr[5];
    }
Я вписал 5(см. язык ar).
А можно зделать как то универсально, не зная сколько будет в array ?
Не задавай глупых вопросов, не услышишь вранья.

Dieser Beitrag wurde von Ratibor (am 10. Februar 2009, 00:26, vor 15 Jahre) bearbeitet
dervan
#51 10. Februar 2009, 01:15
Можно так:
$last = count($expr) - 1;
$res = $digit . (($last >= 0 && $plural <= $last) ? " {$expr[$plural]}" : '');
Здесь предполагается, что $plural не может быть меньше 0.

Глянул сейчас в getPlural() ветку для английского языка - неправильно будет работать. Параметр $plural на входе getPlural() - это остаток от деления на 100, т.е. для 1, 101, 201 и т.д. будут выводиться слова как для 1. Надо поправить эту строку
$i=preg_replace('/[^0-9]+/s','',$digit)%100; //intval не всегда корректно работает
на такую
$i=preg_replace('/[^0-9]+/s','',$digit);

А в функцище getPlural() в ветке для русского языка перед return добавить
$plural %= 100;

Ratibor, если хочешь - давай я перепишу всё это дело покомпактнее и без замеченных ошибок, а ты потом посмотришь.
Ratibor
#52 10. Februar 2009, 01:26
# dervan : Ratibor, если хочешь - давай я перепишу всё это дело покомпактнее и без замеченных ошибок, а ты потом посмотришь.

Переписывай, лично для меня не важно кто это напишет, а важно чтобы это было универсально и работало :-)
Я пока вот на чем остановился.
С русским вроде все нормально теперь работает.
И избавился от case и array теперь может быть любой длинны.
А так же выкинул языки где нет склонений, они все равно не пройдут через if(is_array($expr)).

function declension($digit,$expr,$onlyword=false) {
    if(is_array($expr))
    {
	global $cfg, $lang;

	$i=preg_replace('/[^0-9]+/s','',$digit);
	if($onlyword) $digit='';

	$plural= getPlural ($i, $lang);
	$res=$digit.' '.$expr[$plural];
	}
    else
    {
    $res = $digit.' '.$expr;
    }
 
        return trim($res);

}

function getPlural($plural, $locale) {

	switch($locale) {
		case 'af':
		case 'az':
		case 'bn':
		case 'bg':
		case 'ca':
		case 'da':
		case 'de':
		case 'el':
		case 'en':
		case 'eo':
		case 'es':
		case 'et':
		case 'eu':
		case 'fa':
		case 'fi':
		case 'fo':
		case 'fur':
		case 'fy':
		case 'gl':
		case 'gu':
		case 'ha':
		case 'he':
		case 'hu':
		case 'is':
		case 'it':
		case 'ku':
		case 'lb':
		case 'ml':
		case 'mn':
		case 'mr':
		case 'nah':
		case 'nb':
		case 'ne':
		case 'nl':
		case 'nn':
		case 'no':
		case 'om':
		case 'or':
		case 'pa':
		case 'pap':
		case 'ps':
		case 'pt':
		case 'so':
		case 'sq':
		case 'sv':
		case 'sw':
		case 'ta':
		case 'te':
		case 'tk':
		case 'ur':
		case 'zh':
		case 'zu':
			return ($plural == 1) ? 1 : 0;

		case 'am':
		case 'bh':
		case 'fil':
		case 'fr':
		case 'gun':
		case 'hi':
		case 'ln':
		case 'mg':
		case 'nso':
		case 'uk':
		case 'ti':
		case 'wa':
			return (($plural == 0) || ($plural == 1)) ? 1 : 0;

		case 'be':
		case 'bs':
		case 'hr':
		case 'ru':
		case 'sr':
		case 'ua':
			$plural %= 100;
			return (5 <= $plural && $plural <= 20) ? 2 : ((1 == ($plural %= 10)) ? 0 : ((2 <= $plural && $plural <= 4) ? 1 : 2));

		case 'cs':
		case 'sk':
			return ($plural == 1) ? 1 : (($plural >= 2) && ($plural <= 4)) ? 2 : 0;

		case 'ga':
			return ($plural == 1) ? 1 : ($plural == 2) ? 2 : 0;

		case 'lt':
			return (($plural % 10 == 1) && ($plural % 100 != 11)) ? 1 : (($plural % 10 >= 2) && (($plural % 100 < 10) || ($plural % 100 >= 20))) ? 2 : 0;

		case 'sl':
			return ($plural % 100 == 1) ? 1 : ($plural % 100 == 2) ? 2 : (($plural % 100 == 3) || ($plural % 100 == 4)) ? 3 : 0;

		case 'mk':
			return ($plural % 10 == 1) ? 1 : 0;

		case 'mt':
			return ($plural == 1) ? 1 : (($plural == 0) || (($plural % 100 > 1) && ($plural % 100 < 11))) ? 2 : (($plural % 100 > 10) && ($plural % 100 < 20)) ? 3 : 0;

		case 'lv':
			return ($plural == 0) ? 1 : (($plural % 10 == 1) && ($plural % 100 != 11)) ? 2 : 0;

		case 'pl':
			return ($plural == 1) ? 1 : (($plural % 10 >= 2) && ($plural % 10 <= 4) && (($plural % 100 < 10) || ($plural % 100 > 29))) ? 2 : 0;

		case 'cy':
			return ($plural == 1) ? 1 : ($plural == 2) ? 2 : (($plural == 8) || ($plural == 11)) ? 3 : 0;

		case 'ro':
			return ($plural == 1) ? 1 : (($plural == 0) || (($plural % 100 > 0) && ($plural % 100 < 20))) ? 2 : 0;

		case 'ar':
			return ($plural == 0) ? 1 : ($plural == 1) ? 2 : ($plural == 2) ? 3 : (($plural >= 3) && ($plural <= 10)) ? 4 : (($plural >= 11) && ($plural <= 99)) ? 5 : 0;
	}
}
Не задавай глупых вопросов, не услышишь вранья.

Dieser Beitrag wurde von Ratibor (am 10. Februar 2009, 01:39, vor 15 Jahre) bearbeitet
dervan
#53 10. Februar 2009, 01:36
$res=$digit.' '.$expr[$plural];

Здесь может оказаться, что в lang-файле массив меньшего размера, и $plural выйдет за его границу.

В getPlural() не надо убирать return 0; - он должен быть по default'у.

Dieser Beitrag wurde von dervan (am 10. Februar 2009, 03:16, vor 15 Jahre) bearbeitet
esclkm
#54 10. Februar 2009, 01:39
а цифры класса 11 12 13 у тебя нормально обрабатываются?
littledev.ru - мой маленький зарождающийся блог о котонти.
снижение стоимости программирования и снижение стоимости производства разные вещи. Первое можно скорее сравнить с раздачей работникам дешевых инструментов, чем со снижением зарплаты
Ratibor
#55 10. Februar 2009, 01:41
# dervan : $res=$digit.' '.$expr[$plural];

Здесь может оказаться, что в lang-файле массив меньшего размера, и $plural выйдет за его границу.
Пусть правильно делают ланг файлы :-)
Не задавай глупых вопросов, не услышишь вранья.
dervan
#56 10. Februar 2009, 01:47
# Ratibor : Пусть правильно делают ланг файлы :-)
Да проверить и всё - делов-то. :)
Ratibor
#57 10. Februar 2009, 01:47
# esclkm : а цифры класса 11 12 13 у тебя нормально обрабатываются?
Если ты имеешь в виду именно эти три цифры по отдельности, то правильно

# dervan : Да проверить и всё - делов-то. :)
Если зделать проверку, во первых код будет длиньше, а во вторых глюк не сразу заметят :)
Не задавай глупых вопросов, не услышишь вранья.

Dieser Beitrag wurde von Ratibor (am 10. Februar 2009, 01:50, vor 15 Jahre) bearbeitet
dervan
#58 10. Februar 2009, 02:39
# Ratibor : Если зделать проверку, во первых код будет длиньше, а во вторых глюк не сразу заметят :)
Заметят - вместо слова будет пустая строка. :)
Вариант с проверкой добавил и закомментировал, а там дело хозяйское.

Подправил, получилось практически то же, что и у тебя, только я отформатировал текст в соответствии с Cotinti coding conventions.
function declension($digit, $expr, $onlyword = false)
{
	if (!is_array($expr))
	{
		return trim(($onlyword ? '' : "$digit ") . $expr);
	}

	global $lang;

	$i = preg_replace('#[^0-9]+#', '', $digit);
	$plural = get_plural($i, $lang);
	return trim(($onlyword ? '' : "$digit ") . $expr[$plural]);
//	$cnt = count($expr);
//	return trim(($onlyword ? '' : "$digit ") . (($cnt > 0 && $plural < $cnt) ? $expr[$plural] : ''));
}

Со второй функцищей непонятки - здесь было так
            case 'am':
            case 'bh':
            case 'fil':
            case 'fr':
            case 'gun':
            case 'hi':
            case 'ln':
            case 'mg':
            case 'nso':
            case 'xbr':
            case 'ti':
            case 'wa':
а в твоём последнем варианте case 'xbr': превратился в case 'uk': - оставил как в первоначальном варианте, плюс добавил default:
function get_plural($plural, $locale)
{
	switch ($locale)
	{
		case 'af':
		case 'az':
		case 'bn':
		case 'bg':
		case 'ca':
		case 'da':
		case 'de':
		case 'el':
		case 'en':
		case 'eo':
		case 'es':
		case 'et':
		case 'eu':
		case 'fa':
		case 'fi':
		case 'fo':
		case 'fur':
		case 'fy':
		case 'gl':
		case 'gu':
		case 'ha':
		case 'he':
		case 'hu':
		case 'is':
		case 'it':
		case 'ku':
		case 'lb':
		case 'ml':
		case 'mn':
		case 'mr':
		case 'nah':
		case 'nb':
		case 'ne':
		case 'nl':
		case 'nn':
		case 'no':
		case 'om':
		case 'or':
		case 'pa':
		case 'pap':
		case 'ps':
		case 'pt':
		case 'so':
		case 'sq':
		case 'sv':
		case 'sw':
		case 'ta':
		case 'te':
		case 'tk':
		case 'ur':
		case 'zh':
		case 'zu':
			return ($plural == 1) ? 1 : 0;

		case 'am':
		case 'bh':
		case 'fil':
		case 'fr':
		case 'gun':
		case 'hi':
		case 'ln':
		case 'mg':
		case 'nso':
		case 'xbr':
		case 'ti':
		case 'wa':
			return (($plural == 0) || ($plural == 1)) ? 1 : 0;

		case 'be':
		case 'bs':
		case 'hr':
		case 'ru':
		case 'sr':
		case 'ua':
			$plural %= 100;
			return (5 <= $plural && $plural <= 20) ? 2 : ((1 == ($plural %= 10)) ? 0 : ((2 <= $plural && $plural <= 4) ? 1 : 2));

		case 'cs':
		case 'sk':
			return ($plural == 1) ? 1 : (($plural >= 2) && ($plural <= 4)) ? 2 : 0;

		case 'ga':
			return ($plural == 1) ? 1 : ($plural == 2) ? 2 : 0;

		case 'lt':
			return (($plural % 10 == 1) && ($plural % 100 != 11)) ? 1 : (($plural % 10 >= 2) && (($plural % 100 < 10) || ($plural % 100 >= 20))) ? 2 : 0;

		case 'sl':
			return ($plural % 100 == 1) ? 1 : ($plural % 100 == 2) ? 2 : (($plural % 100 == 3) || ($plural % 100 == 4)) ? 3 : 0;

		case 'mk':
			return ($plural % 10 == 1) ? 1 : 0;

		case 'mt':
			return ($plural == 1) ? 1 : (($plural == 0) || (($plural % 100 > 1) && ($plural % 100 < 11))) ? 2 : (($plural % 100 > 10) && ($plural % 100 < 20)) ? 3 : 0;

		case 'lv':
			return ($plural == 0) ? 1 : (($plural % 10 == 1) && ($plural % 100 != 11)) ? 2 : 0;

		case 'pl':
			return ($plural == 1) ? 1 : (($plural % 10 >= 2) && ($plural % 10 <= 4) && (($plural % 100 < 10) || ($plural % 100 > 29))) ? 2 : 0;

		case 'cy':
			return ($plural == 1) ? 1 : ($plural == 2) ? 2 : (($plural == 8) || ($plural == 11)) ? 3 : 0;

		case 'ro':
			return ($plural == 1) ? 1 : (($plural == 0) || (($plural % 100 > 0) && ($plural % 100 < 20))) ? 2 : 0;

		case 'ar':
			return ($plural == 0) ? 1 : ($plural == 1) ? 2 : ($plural == 2) ? 3 : (($plural >= 3) && ($plural <= 10)) ? 4 : (($plural >= 11) && ($plural <= 99)) ? 5 : 0;

		default:
			return 0;
	}
}
Ratibor
#59 10. Februar 2009, 02:44
# dervan : Вариант с проверкой добавил и закомментировал, а там дело хозяйское.
Т.е если раскоментировать то получится так ?
function declension($digit, $expr, $onlyword = false)
{
	if (!is_array($expr))
	{
		return trim(($onlyword ? '' : $digit) . " $expr");
	}

	global $lang;

	$i = preg_replace('#[^0-9]+#', '', $digit);
	if ($onlyword)
	{
		$digit = '';
	}
	$plural = get_plural($i, $lang);
	$cnt = count($expr);
	return trim($digit . (($cnt > 0 && $plural < $cnt) ? " {$expr[$plural]}" : ''));
}
# dervan : а в твоём последнем варианте case 'xbr': превратился в case 'uk': - оставил как в первоначальном варианте
xbr - это великобритания, я ее и заменил на uk, как у нас в движке.

Ну что включаем этот код в движок ?
Trustmaster что скажешь ?

Для всех языков что выше русского вроде все зделали, а для остальных языков, если что неправильно сделали, пусть сами правят, благо теперь все понятно зделано и легко можно добавлять/редактировать/удвлять языки.
Не задавай глупых вопросов, не услышишь вранья.
dervan
#60 10. Februar 2009, 02:52
Почти так - я только что поправил свой предыдцущий пост. :) Т.е. теперь с проверкой у меня написано так
function declension($digit, $expr, $onlyword = false)
{
	if (!is_array($expr))
	{
		return trim(($onlyword ? '' : "$digit ") . $expr);
	}

	global $lang;

	$i = preg_replace('#[^0-9]+#', '', $digit);
	$plural = get_plural($i, $lang);
	$cnt = count($expr);
	return trim(($onlyword ? '' : "$digit ") . (($cnt > 0 && $plural < $cnt) ? $expr[$plural] : ''));
}

C 'xbr' как 'uk' что-то не понял. Для case 'en': имеем
            return ($plural == 1) ? 1 : 0;
а для case 'xbr': - другое
            return (($plural == 0) || ($plural == 1)) ? 1 : 0;

ErsteVorherige1234567NächsteLetzte