Войти

Показать полную графическую версию : Обработка строки preg_replace


venuko
28-01-2009, 19:18
$words=array('World','пять и два','государств','Семь');
$open_tags=array('<a href="ssilka1">','<a href="ssilka2">','<a href="ssilka3">','<a href="ssilka4">');
$close_tags=array('</a>','</a>','</a>','</a>');

function highlight_first($text, $words, $open_tags, $close_tags) {
$arReplace = array();
for($i=0; $i<count($words); $i++) {
//$words[$i] = '/('.preg_quote($words[$i]).')/iu';
$words[$i] = "/\b(".preg_quote($words[$i]).")\b/";
//$words[$i] = "/(?<![a-z0-9а-я])(".preg_quote($words[$i]).")(?![a-z0-9а-я])/iu";
$arReplace[]= $open_tags[$i]. '\1'. $close_tags[$i];
}
$text = preg_replace($words, $arReplace, $text, 1);
return $text;
}

$text = "Семь и ещё world World семь Буквы world разные и т.д. пять и два потом World Пять и два государственный. Семь государств и Шесть паШесть";
$text=highlight_first($text,$words,$open_tags,$close_tags);

echo $text;

Результат работы скрипты такой: <a href="ssilka4">Семь</a> и ещё world <a href="ssilka1">World</a> семь Буквы world разные и т.д. <a href="ssilka2">пять и два</a> потом World Пять и два государственный. Семь <a href="ssilka3">государств</a> и Шесть паШесть

А должен быть: Результат работы скрипты такой: <a href="ssilka4">Семь</a> и ещё <a href="ssilka1">world</a> World семь Буквы world разные и т.д. <a href="ssilka2">пять и два</a> потом World Пять и два государственный. Семь <a href="ssilka3">государств</a> и Шесть паШесть


Т.е. скрипт в тексте оборчивает нужными тегами самые первые вхождения слов (повторения не оборачивает), слова для оборачивания в массиве, также теги. Проблема в том что что-то с регистром, т.е. слово World обернулось, а должно было world с маленькой буквы, так как оно первое вхождение. Подскажите в чем проблема, плиз?

Igor_I
28-01-2009, 21:05
т.е. слово World обернулось, а должно было world с маленькой буквы »
Так ты сам его убрал из массива :)
//$words[$i] = "/(?<![a-z0-9а-я])(".preg_quote($words[$i]).")(?![a-z0-9а-я])/iu"; буковку i надо разместить до слэша. Именно i отвечает за регистронезависимость.
Ну, а вообще регулярки мне всё время даются трудно.

Igor_I
28-01-2009, 21:30
Нет я не прав.
$words[$i] = '/(?<=\s|^)(' . preg_quote($words[$i]) . ')(?=\s|$)/i';
Смотри здесь - http://forum.oszone.net/post-1011765-10.html

venuko
28-01-2009, 21:39
заменил на это вроде пашет:

$words[$i] = "/\b(".preg_quote($words[$i]).")\b/i";

это:
$words[$i] = '/(?<=\s|^)(' . preg_quote($words[$i]) . ')(?=\s|$)/i'; »

в случае такого текста и массива замены, не будет как нужно работать:

$words=array('World','пять и два','государств','СеМь','Два и Восемь','два и восемь');
$open_tags=array('<a href="ssilka1">','<a href="ssilka2">','<a href="ssilka3">','<a href="ssilka4">','<a href="ssilka5">','<a href="ssilka6">');
$close_tags=array('</a>','</a>','</a>','</a>','</a>','</a>');

$text = "Семь и ещё world World семь Буквы world разные и т.д. пять и два потом World Пять и два государственный. Семь государств и Шесть паШесть. Два и Восемь и ещё потом буквы два и восемь";

Sham
29-01-2009, 03:10
не будет как нужно работать »
все будет работать - везде используется подмаска (и везде одна)...
если кодировка системы не соответствует, то флаг i не будет работать, поскольку не найдется другой регистр буквы (у нелатиницы)... т.е. нужно юзать setlocale с нужной кодировкой...

venuko
29-01-2009, 09:29
все будет работать - везде используется подмаска (и везде одна)...
если кодировка системы не соответствует, то флаг i не будет работать, поскольку не найдется другой регистр буквы (у нелатиницы)... т.е. нужно юзать setlocale с нужной кодировкой... »


а вотс setlocale не пойму как её применить, на сайте кодировка wuindows-1251

не пинайте :) я только учусь, подскажите

Sham
29-01-2009, 10:39
// для всех типов функций, для кириллицы

@setlocale(LC_ALL, 'ru_RU.CP1251');

venuko
29-01-2009, 10:49
// для всех типов функций, для кириллицы
@setlocale(LC_ALL, 'ru_RU.CP1251'); »

в CMS это возможно уже есть, так как тот код выводится в модуле, то думаю в самом модуле в начале это кода высталвять это @setlocale(LC_ALL, 'ru_RU.CP1251'); не нужно, так ли это?

Sham
29-01-2009, 11:04
текущую локаль можно проверить
// выведет текущую

echo @setlocale(LC_ALL, NULL);
и если стоит 1251, то не нужно... локаль должна соответствовать кодировке текста.

venuko
29-01-2009, 11:19
локаль проверил она такая KOI8-R/ru_RU

Sham
29-01-2009, 11:40
лучше установите локаль только для строковых функций... вставьте строку до обработки текста...
// для функций обработки строк, для кириллицы 1251
// название локали может быть разным, в зависимости от системы

@setlocale(LC_CTYPE, 'ru_RU.CP1251');

venuko
29-01-2009, 13:45
хм, когда через CMS добавляю текст и словосочетания то они выделяются, а экспоритровал другую базу, и в ней не выделяются слова, что-то с кодировкой?

Artem-Samsung
11-02-2010, 20:06
$i=1;
do {
$comments['message'] = str_replace(":smile".$i.":", "<img src='/smiles/s".$i.".png' alt='' />", $comments['message']);
$i++;
} while($i<21);

Можно это как то тоже оптимизировать методом preg_replace ?

Типа так?
$t = preg_replace("~:smile([0-9]*):~", "<img src=\"/smiles/$1\.png\" />", $t);

Sham
11-02-2010, 23:33
str_replace быстрее будет, но это требует проверки времени выполнения. Сделайте два варианта, и проверьте время выполнения, выберите тот, где быстрее.

в строке замены экранировать не нужно (кроме кавычек), там не регулярное выражение.

Artem-Samsung
11-02-2010, 23:37
$list['content'] = stripslashes(preg_replace("~:smile([0-9]*):~", "<img src=\"/smiles/s$1\.png\" />", $comments['message']));
Да, так работает :)
А вот подскажите пожалуйста, как проверить скорость выполнения?
Я не думаю, что это на столько важно. Там текста немного. А вот записывается в одну строчку акуратней) но спасибо, буду знать)

Sham
11-02-2010, 23:49
stripslashes( »
это зачем?s$1\.png »экран уберите тут.как проверить скорость выполнения? »
с помощью microtime (http://docs.php.net/manual/ru/function.microtime.php) - ставите в коде метки в начале и конце, и вычисляете разницу.




© OSzone.net 2001-2012