Текст по "вариантному" шаблону

Тема в разделе "PHP", создана пользователем Super_BOT, 11 дек 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. Super_BOT

    Super_BOT

    Регистр.:
    21 апр 2009
    Сообщения:
    256
    Симпатии:
    28
    Во многих программах, и на многих сайтах встречаются контрукции наподобие этой
    [Предложение1|Предложение2|Предложение3]
    И на выходе мы можем получить одно из трех предложений.
    Причем таких вариантных шаблонов в одном тексте может быть довольно много.

    Есть ли готовая функция которая работает с такими шаблонами? Если есть, поделитесь пожалуйста.
     
  2. saen

    saen

    Регистр.:
    6 авг 2006
    Сообщения:
    756
    Симпатии:
    129
    Опиши задачу яснее, непонятно что тебе надо получить и как это должно работать, по какому критерию идет выбор? вручную или автоматически? (и не забывай, что ты пишешь в разделе PHP)
     
  3. Super_BOT

    Super_BOT

    Регистр.:
    21 апр 2009
    Сообщения:
    256
    Симпатии:
    28
    Нужна функция на пхп, которая принимает входной шаблон (пример ниже) а на выходе дает рандомную строку, составленную по этому шаблону

    Пример шаблона:

    "[Ваш|Твой|Свой] [любимый|лучший] [фильм|день недели|праздник]."

    А на выходе может получиться например следующее
    "Ваш любимый фильм"
    "Твой лучший праздник"
    "Ваш лучший фильм"

    и так далее.
    Выбор из шаблона идет наугад, в первой скобках [] выбирается один вариант из 3ех, в остальных соответсвенно из 2ух
     
  4. saen

    saen

    Регистр.:
    6 авг 2006
    Сообщения:
    756
    Симпатии:
    129
    PHP:
    $text='[Ваш|Твой|Свой] [любимый|лучший] [фильм|день недели|праздник]';

    #разбиваем на шаблон на группы []
    preg_match_all('/\[(.*?)\]/'$text$m);

    #получаем массив с вариантами
    foreach($m[1] as $k => $v)
    {
        
    $m[1][$k] = explode('|'$m[1][$k]);
    }
    #теперь в $m[1] содержатся 3 массива с вариантами

    #генерируем случайный вывод
    $str '';
    foreach(
    $m[1] as $tpl)
    {
        
    $str .= $tpl[array_rand($tpl)].' ';
    }

    echo 
    $str;
     
    Super_BOT нравится это.
  5. Super_BOT

    Super_BOT

    Регистр.:
    21 апр 2009
    Сообщения:
    256
    Симпатии:
    28
    все отлично, большое спасибо, только можно еще как-нибудь немного доработать, чтобы в тексте были еще статические части.

    Пример:

    $text='[Ваш|Твой|Свой] любимый [фильм|день недели|праздник]';

    А на выходе соответственно получали

    Ваш любимый фильм
    Твой любимый праздник

    и так далее.

    В текущем варианте скрипта, статические части я так понимаю никак не запоминаются.
     
  6. trooll

    trooll PHP кодер

    Регистр.:
    22 дек 2008
    Сообщения:
    503
    Симпатии:
    116
    Эх так и быть поделюсь своей старой функцией:

    PHP:
    <?PHP
    ##############################################################################
    #    АВТОР СКРИПТА: trooll
    #    ICQ: 994-93-94
    #    E-MAIL: trooll88@gmail.com
    ##############################################################################    

    function genRndAncor($v 0) {
            if(!
    $v)
            {
                return 
    false;
            }

            while(
    true)
            {
                if(
    preg_match("#\[.+\]#"$v) == 0)
                {
                    return 
    $v;
                }

                
    $ind_start_last strrpos($v"[");

                
    $str_part1 substr($v0$ind_start_last);

                
    $str_part2 substr($v$ind_start_laststrlen($v));

                
    $ind_end_first strpos($str_part2"]");

                
    $str_part3 substr($str_part2, ($ind_end_first 1), strlen($str_part2));

                
    $str_part2 substr($str_part21, ($ind_end_first 1));

                
    $str_part2 array_rand(array_flip(explode("|"$str_part2)));

                
    $v $str_part1.$str_part2.$str_part3;
            }
        }
    ?>
    ВНИМАНИЕ! Функция генерит одну случайную вариацию, генерация всех возможных вариаций в данной функции не предусмотрена.

    Функция работает довольно быстро так как очень сложно распарски в ней нет, и позволяет работать с довольно объемными шаблонами.

    P.S.: Прошу строга не судить данная функция была написана в очень далекое время, в данный момент данная функция уже не актуальная так как появилась новая вариация, по этой причине собственно и выкладываю ее в паблик. Но не смотря на ее преклонный возраст она все равно работает довольно шустро.
     
    Super_BOT нравится это.
  7. Alternator

    Alternator

    Регистр.:
    23 мар 2009
    Сообщения:
    295
    Симпатии:
    145
    так, не?
    PHP:
    <?php
    $text
    ='[Ваш|Твой|Свой] [любимый|лучший] [фильм|день недели|праздник] в этом году';

    $text preg_replace_callback('/\[([^\]]*)\]/''get_random_piece'$text);
    echo 
    $text;
    function 
    get_random_piece($matches){
        
    $temp explode('|'$matches[1]);
        return 
    $temp[array_rand($temp)];
    }
    видел когда-то решение задачи вообще в одну строку кода
    но там использовался e модификатор регулярок, что намекает
     
    Super_BOT нравится это.
  8. trooll

    trooll PHP кодер

    Регистр.:
    22 дек 2008
    Сообщения:
    503
    Симпатии:
    116
    Предлагаю оставить тему открытой!

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

    Так что думаю стоит оставить тему открытой.
     
  9. Super_BOT

    Super_BOT

    Регистр.:
    21 апр 2009
    Сообщения:
    256
    Симпатии:
    28
    Кому интересно отдал предпочтение функции trooll'a, так как она отлично обрабатывает и вложенные подшаблоны

    Пример входной строки (уровень вложенности = 3:(
    "[Ваш [1[3|4] | 2[3|4]] | Твой [ 1[3|4] | 2] [3|4] | Свой[ 1[3|4]|2[3|4]] ] [любимый|лучший] [фильм|день недели|праздник] в этом году"

    Выдает
    "Твой143 лучший день недели в этом году"
    "Свой14 любимый фильм в этом году"
    и тд.
     
  10. B0nuse

    B0nuse Постоялец

    Регистр.:
    6 июн 2009
    Сообщения:
    106
    Симпатии:
    21
    Думаю, в функции troll'a не мешало бы перевести шаблон текста, например, в кодировку UTF8 и заменить соответствующие функции на их mb_ аналоги.
    Таким образом, функция приобретет некую универсальность.
     
Статус темы:
Закрыта.