Ru-MaNGOS

Вернуться   Ru-MaNGOS > Документация > Языки программирования

Важная информация

Языки программирования Изучаем С++, Sql, php, Lua, Python

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 31.10.2010, 00:00   #1
Hantet
Ученый
 
Аватар для Hantet
 
Регистрация: 07.03.2010
Адрес: Санкт-Петербург
Сообщений: 163
Сказал(а) спасибо: 124
Поблагодарили 111 раз(а) в 52 сообщениях
Hantet Скоро придёт к известностиHantet Скоро придёт к известности
Отправить сообщение для Hantet с помощью ICQ
По умолчанию Регулярные выражения

"Похожие темы не найдены" - так молвил форум при введённом поле "Заголовок".

Сразу к делу.
Пытаюсь составить регулярное выражение на php.
Изучил литературу, ссылки на которую мне выдал гугл.

Дано:
Строка, в которой может находится ноль или несколько выражений, отделённых от строки символами "{" и "}" соответственно.
После открывающей фигурной скобки идёт символ "@", затем содержимое текстового блока.
Текстовый блок состоит из 4ёх частей, разделённых между собой символом ";":
1. 1-е окончание.
2. 2-е окончание.
3. 3-е окончание.
4. Число-параметр.

Пример строки:
На Вашем счёте {@рубль;рубля;рублей;5}.

Выходящее значение:
На Вашем счёте 5 рублей.

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

Пытался сделать так:
Код:
$str = 'На Вашем счёте {@рубль;рубля;рублей;5}.';
preg_match_all("/[{][@][;a-zA-Zа-яА-Я0-9]+[}]/", $str, $matches);
if(count($matches) == 0)
return false;

...
Функция возвращает false.
Буду очень благодарен за помощь.



Добавлено через 1 час 12 минут
Проблему решил сам, всем спасибо
Пожалуй, поделюсь кодом

Функция:
Код:
public function ending($str = null)
{
	if($str == null)
		return false;
	
	if(!preg_match_all("/{[@]([a-zA-Zа-яА-Я0-9;]+)}/", $str, $arr))
		return false;

	$cnt = count($arr);
	if($cnt < 2)
		return false;

	for($i=1;$i<$cnt;$i++)
	{
		foreach($arr[$i] as $one)
		{
			$end = explode(';', $one);
			if(strlen($end[3]) == 0)
				continue;
			
			$num100 = $end[3] % 100;
			$num10 = $end[3] % 10;
			
			if($num100 >= 5 && $num100 <= 20)
				$replace = $end[2];
			else if($num10 == 0)
				$replace = $end[2];
			else if($num10 == 1)
				$replace = $end[0];
			else if($num10 >= 2 && $num10 <= 4)
				$replace = $end[1];
			else if($num10 >= 5 && $num10 <= 9)
				$replace = $end[2];
			else
				$replace = $end[1];
			
			$search = '{@'.$end[0].';'.$end[1].';'.$end[2].';'.$end[3].'}';
			$str = str_replace($search, $end[3].' '.$replace, $str);
		}
	}
	return $str;
}
Вызывается таким нехитрым способом:
Код:
$online = 272; //предположим
$txt = "Сейчас в игре {@человек;человека;человек;$online}.";
echo ending($txt);
Результат выполнения функции следующий:
Сейчас в игре 272 человека.

Соль данной функции в том, что она позволяет делать следующее:
Код:
$str = "Всего в игре {@человек;человека;человек;$online}.<br/>";
$str.= "Из них {@орк;орка;орков;$orc} и {@гном;гнома;гномов;$gnome}";
echo ending($txt);
__________________
Галя: Вот почему когда я пуск делаю и по ярлыку две то запускается, а если вот мне к примеру надо не из пуска её то ничего и в красном показывает, а надо ведь чтобы квадратик жёлтенький открывал и там 3 кнопки должно быть?
admin: О Боже!
admin: Кто-нибудь, пришлите ко мне уборщицу, пусть мой мозг со стен и потолка отмоет

Последний раз редактировалось Hantet; 30.10.2010 в 22:57.
Hantet вне форума   Ответить с цитированием
Старый 31.10.2010, 00:07   #2
LordJZ
Супер-модератор
 
Аватар для LordJZ
 
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
LordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранита
По умолчанию

Напомнило «каждому символу — по домику».

Тег php кривой, потому без подсветки:
Код:
$str = 'На Вашем счёте {@рубль;рубля;рублей;5}.';
// Создает callback-функцию, обрабатывающую каждое попадание конструкции {@a;b;c;[d;[e;...]];x}
$callback = function ($matches)
{
	$words = explode(';', $matches[1]); // Разделяем a;b;c на array(a, b, c)
	$n = $matches[2]; // Число x
	// Взято на просторах этого вашего интернета
	return $n.' '.$words[$n%10==1&&$n%100!=11?0:($n%10>=2&&$n%10<=4&&($n%100<10||$n%100>=20)?1:2)];
};
echo preg_replace_callback('/{@([^}]+);(\d+)}/', $callback, $str);
LordJZ вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
Hantet (31.10.2010)
Старый 31.10.2010, 00:11   #3
Hantet
Ученый
 
Аватар для Hantet
 
Регистрация: 07.03.2010
Адрес: Санкт-Петербург
Сообщений: 163
Сказал(а) спасибо: 124
Поблагодарили 111 раз(а) в 52 сообщениях
Hantet Скоро придёт к известностиHantet Скоро придёт к известности
Отправить сообщение для Hantet с помощью ICQ
По умолчанию

Супер, спасибо, буду вникать
Всё-таки хорошо, что я дошёл до цели сам, пусть криво, долго и громоздко, но сам!
Так бы никогда и не начал работать с регулярками.
__________________
Галя: Вот почему когда я пуск делаю и по ярлыку две то запускается, а если вот мне к примеру надо не из пуска её то ничего и в красном показывает, а надо ведь чтобы квадратик жёлтенький открывал и там 3 кнопки должно быть?
admin: О Боже!
admin: Кто-нибудь, пришлите ко мне уборщицу, пусть мой мозг со стен и потолка отмоет
Hantet вне форума   Ответить с цитированием
Старый 31.10.2010, 17:36   #4
Праведник
Пользователь
 
Регистрация: 27.03.2010
Сообщений: 80
Сказал(а) спасибо: 12
Поблагодарили 25 раз(а) в 13 сообщениях
Праведник На верном пути
По умолчанию

Зачем вообще регулярки?)

Код:
function number_ending($number, $ending0, $ending1, $ending2) { 
    $num100 = $number % 100; 
    $num10 = $number % 10; 
    if ($num100 >= 5 && $num100 <= 20) { 
        return $ending0; 
    } else if ($num10 == 0) { 
        return $ending0; 
    } else if ($num10 == 1) { 
        return $ending1; 
    } else if ($num10 >= 2 && $num10 <= 4) { 
        return $ending2; 
    } else if ($num10 >= 5 && $num10 <= 9) { 
        return $ending0; 
    } else { 
        return $ending2; 
    } 
}
всё... аргументы: число, окончание 1, окончание 2, окончание 3
Праведник вне форума   Ответить с цитированием
Старый 31.10.2010, 17:48   #5
Hantet
Ученый
 
Аватар для Hantet
 
Регистрация: 07.03.2010
Адрес: Санкт-Петербург
Сообщений: 163
Сказал(а) спасибо: 124
Поблагодарили 111 раз(а) в 52 сообщениях
Hantet Скоро придёт к известностиHantet Скоро придёт к известности
Отправить сообщение для Hantet с помощью ICQ
По умолчанию

Праведник, я именно эту функцию и использую, только немного её модернизировал и привязал к регуляркам. Зачем? Очень просто!

Мой движок использует один шаблон (html каркас), в котором в определённых местах (шапка, футер, меню, контент) выставлены блоки а-ля {HEADER}, {BODY} и т.д.
В этом шаблоне исключительно HTML, он у меня даже находится в txt файле

Ну не суть, php читает шаблон, подставляет вместо блоков вида {ИМЯ} содержимое.
И вот у меня появилась идея вынести все элементы, которые отображаются на всех страницах сайта, прямо в шаблон.

Вот как-то так:
Код:
...
<div id="online">В игре {@человек;человека;человек;{online}}.</div>
...
В результате мы получаем сразу на всех страницах сайта строку с показателем онлайна, вида:

<div id="online">В игре 232 человека.</div>

Тем самым эту строку не приходится определять всякий раз на страницах сайта.
__________________
Галя: Вот почему когда я пуск делаю и по ярлыку две то запускается, а если вот мне к примеру надо не из пуска её то ничего и в красном показывает, а надо ведь чтобы квадратик жёлтенький открывал и там 3 кнопки должно быть?
admin: О Боже!
admin: Кто-нибудь, пришлите ко мне уборщицу, пусть мой мозг со стен и потолка отмоет
Hantet вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
Праведник (01.11.2010)
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.



Текущее время: 03:22. Часовой пояс GMT +3.


ru-mangos.ru - Русское сообщество MaNGOS
Главная цель проекта MaNGOS - обучающая, поэтому разрешается использовать исходный код и собранную программу только для образовательных целей.
Вы не можете использовать MaNGOS в коммерческих целях, а также не разрешается устанавливать публичные серверы на базе MaNGOS.
Любое копирование материалов, информации в любом виде без указания источника - форума Ru-MaNGOS будет считаться нарушением авторских прав и нарушением Уголовного Кодекса РФ, ст. 146 ст. 147.
Перевод vBulletin: zCarot