Forum Webscript.Ru

Программирование => PHP => Тема начата: Moe от 20 Октября 2009, 19:51:59

Название: Сортировка после preg_match_all
Отправлено: Moe от 20 Октября 2009, 19:51:59
Здравствуйте. Есть массив с тегами в виде ссылок. Часть тегов имеет несколько типов повторяющихся элементов (Например, тег: "Сюжет — ГМПИ"). Я хочу на основе этих повторений раскидать теги по группам под соответствующие заголовки.

Вот так:

Сюжеты
Тег2, Тег4, Тег5...

Источники
Тег1, Тег3, Тег6...




  foreach ($tags as $tagkey => $onetag) {
    preg_match_all ("/(]>Источник.+<\\/a>$)|(]>Сюжет.+<\\/a>$)|(]>Текст.+<\\/a>$)/", $onetag, $matches, PREG_PATTERN_ORDER);
    $done = preg_replace(\'"(Сюжет\\s—\\s)|(Текст\\s—\\s)|(Источник\\s—\\s)"\', \'\', $matches[1][0] .$matches[2][0] .$matches[3][0] ."\\n");
    echo ($done);    
  }

Вызывая попеременно $matches, у меня получается эти группы выводить, но как приделать к ним заголовок так, чтобы не обходить массив по несколько раз для каждой группы — я не знаю. К тому же, скорее всего этих групп будет около 10. Подскажите, пожалуйста, разумное решение.
Название: Сортировка после preg_match_all
Отправлено: brainkiller от 21 Октября 2009, 00:18:35
Живой пример массива $tags — в студию!
Название: Сортировка после preg_match_all
Отправлено: Moe от 21 Октября 2009, 09:05:21
brainkiller

Речь идет о движке Wordpress и функции wp_tag_cloud. Перед этим кодом есть строка:
$tags = wp_tag_cloud(\'format=array&number=0&order=DESC&orderby=count\');

И данные там такого типа:


...
Сюжет — Тег1
Источник — Тег2
Сюжет — Тег3
Источник — Тег4
...
Название: Сортировка после preg_match_all
Отправлено: brainkiller от 21 Октября 2009, 12:13:16
А не проще ли взять функцию wp_tag_cloud(), посмотреть, что там внутри и написать свою wp_custom_tag_cloud(), которая выдаст нужные данные в нужном формате — вместо того, чтобы парсить вывод существующей функции?
Название: Сортировка после preg_match_all
Отправлено: Moe от 21 Октября 2009, 13:12:02
brainkiller

Я совсем не спец, но мне кажется, что даже создавая свою функцию мне все равно придется тем или иным способом сортировать точно такой же массив тегов. Ну или просто сортировать теги по наличию в них определенных элементов тем же preg_match_all. Или я ошибаюсь?

Ну а с текущим вариантом совсем тухло? Он умеет почти все, кроме как приставлять заголовки к группам тегов, а не к каждому тегу :)

Сейчас, если я напишу:


echo ("Сюжет ".$matches[1][0);
echo ("Текст ".$matches[2][0);


То ожидаемо получу: Сюжет Тег1 Сюжет Тег2 Сюжет Тег3 Текст Тег4 Текст Тег 5 Текст Тег6.
И вопрос в том, как эту проблему разрешить, не инициализируя для каждого шаблона обход всего массива? Вроде такого:

echo ("Сюжет");
foreach ($tags as $tagkey => $onetag) {
    preg_match_all ("/(]>Сюжет.+$)", $onetag, $matches, PREG_PATTERN_ORDER);
    $done = preg_replace(\'"(Сюжетs—s)"\', \'\', $matches[0][0]."\\n");
    echo ($done);    
  }
echo ("Текст");
foreach ($tags as $tagkey => $onetag) {
...
Название: Сортировка после preg_match_all
Отправлено: Moe от 21 Октября 2009, 13:15:15
Для иллюстрации: вот так выглядит функция wp_tag_cloud

function wp_tag_cloud( $args = \'\' ) {
$defaults = array(
\'smallest\' => 8, \'largest\' => 22, \'unit\' => \'pt\', \'number\' => 45,
\'format\' => \'flat\', \'orderby\' => \'name\', \'order\' => \'ASC\',
\'exclude\' => \'\', \'include\' => \'\', \'link\' => \'view\', \'taxonomy\' => \'post_tag\', \'echo\' => true
);
$args = wp_parse_args( $args, $defaults );

$tags = get_terms( $args[\'taxonomy\'], array_merge( $args, array( \'orderby\' => \'count\', \'order\' => \'DESC\' ) ) ); // Always query top tags

if ( empty( $tags ) )
return;

foreach ( $tags as $key => $tag ) {
if ( \'edit\' == $args[\'link\'] )
$link = get_edit_tag_link( $tag->term_id, $args[\'taxonomy\'] );
else
$link = get_term_link( intval($tag->term_id), $args[\'taxonomy\'] );
if ( is_wp_error( $link ) )
return false;

$tags[ $key ]->link = $link;
$tags[ $key ]->id = $tag->term_id;
}

$return = wp_generate_tag_cloud( $tags, $args ); // Here\'s where those top tags get sorted according to $args

$return = apply_filters( \'wp_tag_cloud\', $return, $args );

if ( \'array\' == $args[\'format\'] || empty($args[\'echo\']) )
return $return;

echo $return;
}
Название: Сортировка после preg_match_all
Отправлено: brainkiller от 21 Октября 2009, 14:54:24
$done = preg_replace("(Сюжетs—s)|(Текстs—s)|(Источникs—s)", \'\', \'

Сюжет

\'. $matches[1][0] .\'

Текст

\'. $matches[2][0] .\'

Источник

\'.$matches[3][0] ."\\n");

Проверять лень. :)
Название: Сортировка после preg_match_all
Отправлено: Moe от 21 Октября 2009, 15:05:17
brainkiller

К сожалению, та же беда :(

Сюжет Текст Источник Тег1 Сюжет Текст Источник Тег2 Сюжет Текст Источник Тег3...
Название: Сортировка после preg_match_all
Отправлено: brainkiller от 22 Октября 2009, 01:40:21
Да, точно! Туплю.


$tags = array(
"Сюжет — Тег1
Источник — Тег2
Сюжет — Тег3
Текст — Тег4
Источник — Тег5"
);

foreach ($tags as $tagkey => $onetag) {
    preg_match_all ("/(]+>Текст.+<\\/a>$)|(]+>Источник.+<\\/a>$)|(]+>Сюжет.+<\\/a>$)/m", $onetag, $matches, PREG_SET_ORDER);
    $str1 = "

Текст

"; $str2 = "

Источник

"; $str3 = "

Сюжет

";
    $j = count($matches);
    for($i = 0; $i < $j; $i++) {
$str1 .= @str_replace(\'Текст — \', \'\', $matches[$i][1])." ";
$str2 .= @str_replace(\'Источник — \', \'\', $matches[$i][2])." ";
$str3 .= @str_replace(\'Сюжет — \', \'\', $matches[$i][3])." ";
    }
    echo $str1, $str2, $str3;    
}


Соответственно, первое, что в голову пришло, да на скорую руку набросал. Проверки переменных и прочий лоск давайте уж сами.
Название: Сортировка после preg_match_all
Отправлено: Moe от 22 Октября 2009, 12:30:43
brainkiller

Хех, просто божественно, большое спасибо! :)

Я только убрал знак конца строки $.

preg_match_all ("/(
]+>Текст.+<\\/a>)|(]+>Источник.+<\\/a>)|(]+>Сюжет.+<\\/a>)/m", $onetag, $matches, PREG_SET_ORDER);


Правда, тот массив, с которым я работаю какой-то неправильный и все равно ничего не получается. Видимо, я что-то недопонял с этим wp_tag_cloud, потому что при echo $i; в  вашем случае выводит количество элементов в массиве, например, цифру 5, а в моем такую фигню 00001100011110001100011111111. Также в первом случае при echo $tags; выведет array, а у меня array array array...  Что это может быть?

В любом случае, спасибо, буду разбираться.
Название: Сортировка после preg_match_all
Отправлено: brainkiller от 22 Октября 2009, 13:18:30
Да вовсе не божественно: кабы не подавление ошибок перед оператором замены подстроки, Вас бы нотисами засыпало. :) Говорю же, причёсывать и причёсывать.

Смотрю, у Вас пробел вместо конца строки — надо полагать, пробелами разделены ссылки на тэги? А после последней ссылки пробел есть, или она не попадёт в $matches?

Сделайте print_r($tags) и посмотрите, что там: возможно регулярку снова переделать придётся.
Название: Сортировка после preg_match_all
Отправлено: Moe от 22 Октября 2009, 13:46:01
brainkiller

Нет, пробела в шаблоне нет, почему-то автоматом при посте здесь на форуме там оказывается пробел. При echo $onetag; теги выводятся впритык друг к другу, следовательно, насколько я понимаю, пробела между

Если делать print_r($tags), то в вашем примере выводит:

Array([0] =>
Сюжет — Тег1
Источник — Тег2
Сюжет — Тег3
Текст — Тег4
Источник — Тег5
)

А в моем случае:
Array([0] => Сюжет — Тег1
[1] =>Источник — Тег2
[2] =>Сюжет — Тег3
[3] =>Текст — Тег4
[4] =>Источник — Тег5)
Array([0] => Сюжет — Тег1
[1] =>Источник — Тег2
[2] =>Сюжет — Тег3
[3] =>Текст — Тег4
[4] =>Источник — Тег5)
...


И так, видимо, до бесконечности.
Название: Сортировка после preg_match_all
Отправлено: Moe от 22 Октября 2009, 14:09:05
А при print_r ($matches); совсем запутано:

Array
(
)
Array
(
)
Array
(
    [0] => Array
        (
            [0] =>Сюжет — Тег1
            [1] =>
            [2] =>Сюжет — Тег1
)
)
Array (
    [0] => Array
(
            [0] =>Сюжет — Тег3
            [1] =>
            [2] =>Сюжет — Тег3
...  
Название: Сортировка после preg_match_all
Отправлено: brainkiller от 22 Октября 2009, 16:43:06
Цитировать
А в моем случае:


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

Исправить это просто при помощи implode(), но лучше всё же

$tags = array(
"Сюжет — Тег1",
"Источник — Тег2",
"Сюжет — Тег3",
"Текст — Тег4",
"Источник — Тег5"
);

$str1 = "

Текст

"; $str2 = "

Источник

"; $str3 = "

Сюжет

";
$pat1 = \'Текст — \'; $pat2 = \'Источник — \'; $pat3 = \'Сюжет — \';
foreach($tags as $tag) {
if (strpos($tag, $pat1)) {
$str1 .= str_replace($pat1, \'\', $tag)." ";
}
if (strpos($tag, $pat2)) {
$str2 .= str_replace($pat2, \'\', $tag)." ";
}
if (strpos($tag, $pat3)) {
$str3 .= str_replace($pat3, \'\', $tag)." ";
}
}
echo $str1, $str2, $str3;


…и никаких регулярных выражений!

[OFF]А вопросы надо задавать максимально конкретно![/OFF]
Название: Сортировка после preg_match_all
Отправлено: Moe от 22 Октября 2009, 16:58:06
brainkiller

Теперь все работает должным образом, еще раз большое спасибо!

[OFF]Я настоящий профан в этом деле, но на будущее постараюсь учесть все нюансы и буду формулировать вопрос корректнее :) [/OFF]
Название: Сортировка после preg_match_all
Отправлено: hanslinger от 22 Октября 2009, 23:09:17
Первая настоящая тема за последний год :) а то и три
Название: Сортировка после preg_match_all
Отправлено: Moe от 23 Октября 2009, 08:07:25
hanslinger

:) А в каком смысле?
Название: Сортировка после preg_match_all
Отправлено: hanslinger от 24 Октября 2009, 20:15:25
В смысле что длинный разговор по делу и без тупака :)
Название: Сортировка после preg_match_all
Отправлено: Moe от 24 Октября 2009, 23:30:44
hanslinger

Тогда понятно, приятно, что это так ))
Название: Сортировка после preg_match_all
Отправлено: brainkiller от 25 Октября 2009, 00:21:43
Да. Прямо как в старые добрые времена. :)