Народ, научите как выражение написать. Написал скрипт поиска, функцию вывода результатов хочу как в яндексе, чтобы предложения с подсветкой ключевиков выбрасывала.
Вот так: "|([^\.]+система[^\.]+)|i" - работает,
а как сделать чтобы с вариантами работало???, типа как: "|([^\.]+система|управления[^\.]+)|i"
function high_lite($text,$keys){ // $text= string, $key= array('система','управления')
preg_match_all("|([^\.]+система[^\.]+)|i",$text,$out); // разбиваем на предложения
$all_string= array_unique ($out[1]);
$text= implode('.
',$all_string);
$key= '';
foreach($keys as $v) { // Собираем ключи - "система|управления"
$key .= $v.'|';
}
$key= rtrim ($key, '|');$text=preg_replace("/($key)/si","<b>\\1</b>",$text); // Подсветка ключевиков
return $text;
}
С регексом все в порядке:
$ perl -E '$_="asdsa система asddasd управления dfsdf";$k="система|управления";s/($k)/<b>$1<\/b>/g;say'
asdsa <b>система</b> asddasd <b>управления</b> dfsdf
так что разбирайтесь с особенностями пыха
я наверное не совсем точно привел пример, у меня:
есть выражение "|([^\.]+система[^\.]+)|i" оно ищет в тексте слово "система", и помещает в карман всё предложение (от точки до точки) в котором встретилось это слово.Проблемма в том что когда я хочу искать с логическим или: "|([^\.]+система|управления[^\.]+)|i" чтобы в карман помещалось предложение в котором содержится слово "система" или слово "управления", вот тут почемуто выражение не срабатывает.
А к чему вы тогда привели тот код? И почему в "/($key)/si" вы круглые скобки поставили, а в "|([^\.]+система|управления[^\.]+)|i" упорно не хотите?
На всякий случай уточню
|([^\.]+система|управления[^\.]+)| ищет ( [^\.]+система ) ИЛИ ( управления[^\.]+ ), то есть от точки до система ИЛИ от управления до точки
|([^\.]+(?:система|управления)[^\.]+)| ищет ([^\.]+(система ИЛИ управления) ^\.]+, то есть от точки до (система ИЛИ управления) и до следующей точки
Иллюстрация
$ perl -E '$_="asdsa система asddasd управления dfsdf";s/([^\.]+система|управления[^\.]+)/<b>$1<\/b>/g;say'
<b>asdsa система</b> asddasd <b>управления dfsdf</b>
$ perl -E '$_="asdsa система asddasd управления dfsdf";s/([^\.]+(?:система|управления)[^\.]+)/<b>$1<\/b>/g;say'
<b>asdsa система asddasd управления dfsdf</b>
"|([^\.]+(?:система|управления)[^\.]+)|i" - вот оно, СЧАСТЬЕ :)))
да именно это я и хотел, спасибо вам.З.Ы. код привел в качестве иллюстрации работы функции (огород конечно полный), она сначала выдирает из текста предложения:
preg_match_all("|([^\.]+(?:система|управления)[^\.]+)|i",$text,$out);а потом делает подсветку слов в найденных предложениях:
$text=preg_replace("/(система|управления)/si","<b>\\1</b>",$text);
З.Ы.Ы. а подскажите пожалуйста, как сделать чтобы точка в конце предложения тоже в карман попадала
"|([^\.]+(?:система|управления)[^\.]+)|i"
- здесь попадает лиш - "Заказать - ПОД ЗАКАЗ Система управления устройством"
а надо чтобы - "Заказать - ПОД ЗАКАЗ Система управления устройством."
>З.Ы.Ы. а подскажите пожалуйста, как сделать чтобы точка в конце предложения тоже
>в карман попадалаДык, это совсем просто, добавьте ее в регекс:
([^\.]+(?:система|управления)[^\.]+)\.
я пробовал с круглыми скобками, неработало, я не знал что двоеточие нужно...
Вообще-то это _почти_ одно и то же. Просто () делают ограничение для альтернативы И захват. А (?:) делает только ограничение, БЕЗ захвата. Грамотно использовать именно последний вариант, так как он менее ресурсоемок, но большинство шпарит () без раздумий. То есть вариант с () у вас бы тоже сработал, но я в силу привычки дал вариант с (?:)
Спасибо Вам большое за разъяснения.З.Ы.
Тяжело мне регулярные выражения даются, никак моск не могу научить с ними работать.
Очень рекомендую Mastering Regular Expressions от O'Reilly http://oreilly.com/catalog/9781565922570/. Даже трети изложенного там материала будет достаточно, чтобы больше не иметь проблем с регексами. Можно найти в сети в том числе и на русском.
почитал, все проще оказалось чем я думал. Моск научился закорючки понимать, спасибо!