Сгенерировать все строки по шаблону {одно|другое}

RolCom

Новичок
Сгенерировать все строки по шаблону {одно|другое}

Есть шаблон строки, где в скобках представлен список альтернатив, разделенных знаком |. Как сгенерироват все строки, совпадающие с этим шаблоном?
Например по "{синий|зеленый} {карандаш|мел}" должно вывести:
синий карандаш
синий мел
зеленый карандаш
зеленый мел

З.Ы. Альтернативы могут быть вложенные
 

AmdY

Пью пиво
Команда форума
PHP:
не хочешь, не надо
(молчаливое презрение к неумеющим гуглить)
 

RolCom

Новичок
Код не рабочий. Что и не удивительно, в нем и символы {}| то не ищются. Это че-то не в тему вообще.
 

SiMM

Новичок
Баян - мало того, что уже было, так ещё и задачка-то, в общем, детская.
 

DiMA

php.spb.ru
Команда форума
писатель тупых игровых ботов или спамилки

кстати, скобочки эти пошли с незапамятных времен из языка TCL, который использовали боты eggdrop
так вот, в языке все парсилом автоматом за счет встроенных списков, а эти теперь тупят на пхп
 

DiMA

php.spb.ru
Команда форума
очень просто - обратись к программисту, вопрос не касается пхп
 

SiMM

Новичок
> Не угадали.
Ну конечно, расскажите нам, что это не спам, а прямой маркетинг, угу.
 

RolCom

Новичок
Я же сказал, не для спама. Для спама темболее было бы достаточно генерировать случайные строки по шаблону.

-~{}~ 06.06.09 20:37:

Ну что, кто-нибуть поможет:confused: Задачка-то на нескольско строк.
 

RolCom

Новичок
Не знаю как делать. Чтобы генерировало все строки. Генерацию случайной строки я уже делал раньше
PHP:
<?php
$text='{первый1|первый2|{второй1|второй2|второй3|{ третий|третий2}}|первый3|первый4} {далее1|далее2}';
$flag=true;

while($flag) {
$flag=false;
$text=preg_replace_callback('#{[^{}]*}#', 'replace', $text);
}

function replace($m) {
global $flag;
$a=explode('|', substr($m[0], 1, -1));
$flag=true;
return $a[rand(0, count($a)-1)];
}

print $text;
 

fixxxer

К.О.
Партнер клуба
два варианта
1) рекурсивные pcre - см. в мануале по pcre
2) конечный автомат - см. в статьях на пхпклубе
 

RolCom

Новичок
Рекурсивное pcre уже есть, но как узнать в рекурсии какой вариан прорабатывался, а какой нет?
 

partizan

Новичок
Вот:
PHP:
<?php

	$text=  'бла - бла - бла {первый1|первый2|{второй1|второй2|второй3|{ третий|третий2}}|первый3|первый4} {далее1|далее2} ла л ал а';
	
	function process_text($text)
	{
		$pos = strpos($text, '{');
		if ($pos === false) 
		{
			return array($text);
		}		
		else
		{
			$text1 = substr($text, 0, $pos);
			
			$k = 0;
			$alt = array();
			$a_start = $pos+1;
			
			for ($i=$pos+1; $i<strlen($text); $i++)
			{
				switch ($text[$i])
				{
					case '{':
						$k++;
						break;
					case '}':
						$k--;
						break;
					case '|':
						if (!$k) 
						{
							$alt[] = substr($text, $a_start, $i-$a_start);
							$a_start = $i+1;
						}
						break;
				}
				
				if ($k<0) 
				{
					break;
				}
			}
			
			if ($i>= strlen($text)) 
			{
				// Ошибка: скобка не закрыта
			}
			
			$alt[] = substr($text, $a_start, $i-$a_start);
			
			$alt_processed = array();
			foreach ($alt as $a)
			{
				$alt_processed[] = process_text($a);
			}
			
			return array_merge( array($text1, $alt_processed),		process_text(substr($text, $i+1))	);
		}
	}
	
	$array = process_text($text);
	
	$res = get_all($array);
	
	print_r($res);
	
	function get_all($array)
	{
		if (!is_array($array)) 
		{
			return array($array);
		}
	
		$parts = array();
		
		foreach ($array as $p)
		{
			if (is_array($p)) 
			{
				$alts = array();
				foreach ($p as $alt)
				{
					$alts = array_merge($alts, get_all($alt));
				}
				
				$parts[] = $alts;
			}
			else
			{
				$parts[] = array($p);
			}
		}
		
		$res = array();
		$current = array();
		$indexes = array(0);
		
		$k = 0;
		
		while ($k>=0)
		{
			while ($indexes[$k] < count($parts[$k])) 
			{
				$current[$k] = $parts[$k][$indexes[$k]++];
				
				if ($k+1 < count($parts) ) 
				{
					$k++;
					$indexes[$k] = 0;
				}
				else
				{
					$res[] = implode('', $current);
				}				
			}
			
			$k--;
		}
		
		return $res;
	}
?>
Комментарии за деньги :)
 

tashkentchi

Новичок
Даже у простого шаблона может быть несколько млн результирующих текстов. Зачем они все?
 
Сверху