Перейти к содержимому

Сервис обмена электронных валют


Замена слова на ссылку - помогите с preg_replace

#1 Вячеслав

Вячеслав
  • Пользователь
  • 357 сообщений
  • Репутация: 0
0

Отправлено 04 Апрель 2014 - 14:20

Всем привет! 

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

 

На скрине синим отмечена правильная замена слов на ссылки, а красным не правильная:

 860c6c7837ff.jpg

 

Не могу понять как правильно составить pattern для замены, чтобы заменялись только слова с точным совпадением. Например если термин Атлас, то заменялись только слова Атлас или в ковычках "Атлас", но не часть слова в Атласные.

 

Используется вот такой код, помогите его доработать:

$patterns = array ("#([\W])".$jsArr->title."([^\-*])#Ui");
$replace = array ('$1<a href="'.$jsArr->href.'">'.$jsArr->title.'</a>$2');
$out->mBodytext = preg_replace($patterns, $replace, $out->mBodytext);

 

 

Сообщение отредактировал Вячеслав: 04 Апрель 2014 - 14:20

  • 0

#2 matroskin8

matroskin8
  • Пользователь PRO
  • 767 сообщений
  • Репутация: 143

Отправлено 04 Апрель 2014 - 15:45

Приветствую.

Примерно такой шаблон составил:

#"?(?<![а-я])атлас(?![а-я])"?#iu

Если нет ошибок вида 1атлас и т.п., тогда подходит, как есть. Если есть подобные ошибка, когда в слово атлас могут входить в начале и в конце любые символы, кроме кириллических, тогда в диапазон кириллических символов в начале и конце слова нужно включить эти возможные символы.

Ну и при проверке такой код:

$str = '
аатлас
атлас
атласный
"атлас"
Атлас
"Атлас"
';
$pattern = '#"?(?<![а-я])атлас(?![а-я])"?#iu';
preg_match_all($pattern, $str, $matches);
echo "<pre>" .print_r($matches, true). "</pre>";

выдал, вроде как, нужный результат:

Array
(
    [0] => Array
        (
            [0] => атлас
            [1] => "атлас"
            [2] => Атлас
            [3] => "Атлас"
        )

)

  • 1


#3 Вячеслав

Вячеслав
    Topic Starter
  • Пользователь
  • 357 сообщений
  • Репутация: 0

Отправлено 04 Апрель 2014 - 15:53

Большое спасибо за ответ!

остались проблемы со словами через тире

2b3a577c7be4.jpg


  • 0

#4 matroskin8

matroskin8
  • Пользователь PRO
  • 767 сообщений
  • Репутация: 143

Отправлено 04 Апрель 2014 - 16:03


Большое спасибо за ответ!

Пожалуйста.

 


остались проблемы со словами через тире

Ну так я ведь писал:


когда в слово атлас могут входить в начале и в конце любые символы, кроме кириллических, тогда в диапазон кириллических символов в начале и конце слова нужно включить эти возможные символы

Включите эти тире в шаблон и все будет ок ;)

$str = '
аатлас
атлас
атласный
"атлас"
Атлас
"Атлас"
Атлас-стрейч
Хан-Атлас
';
$pattern = '#"?(?<![а-я-])атлас(?![а-я-])"?#iu';
preg_match_all($pattern, $str, $matches);
echo "<pre>" .print_r($matches, true). "</pre>";

Результат:

Array
(
    [0] => Array
        (
            [0] => атлас
            [1] => "атлас"
            [2] => Атлас
            [3] => "Атлас"
        )

)

  • 0


#5 Вячеслав

Вячеслав
    Topic Starter
  • Пользователь
  • 357 сообщений
  • Репутация: 0

Отправлено 04 Апрель 2014 - 16:09

ага! я вот так сделал:

$patterns = array ('#"?(?<![а-я\-])'.$jsArr->title.'(?![а-я\-])"?#iu');

 правильно что обратный слешь перед тире?


  • 0

#6 matroskin8

matroskin8
  • Пользователь PRO
  • 767 сообщений
  • Репутация: 143

Отправлено 04 Апрель 2014 - 16:12

Он там не нужен, поскольку тире в конце или начале диапазонов является литералом (обычным символом), а не интервальным символом, поэтому его нет смысла экранировать.
  • 0


#7 Вячеслав

Вячеслав
    Topic Starter
  • Пользователь
  • 357 сообщений
  • Репутация: 0

Отправлено 04 Апрель 2014 - 16:23

а как быть вот с этими? 

2b548f7699e1.jpg

если добавить так, то не срабатывает:

$patterns = array ('#"?(?<![а-я-\«])'.$jsArr->title.'(?![а-я-\»])"?#');

  • 0

#8 matroskin8

matroskin8
  • Пользователь PRO
  • 767 сообщений
  • Репутация: 143

Отправлено 04 Апрель 2014 - 16:42


если добавить так, то не срабатывает:

А почему так должно сработать?

Во-первых, угловые скобки перепутаны местами... сейчас вы перед словом атлас поставили открывающую угловую скобку, но ведь должна быть закрывающая, т.е. не «Ментенон« Атлас, а таки «Ментенон» Атлас... то же самое касается скобки после искомого слова: не Атлас »Ментенон», а Атлас «Ментенон»

Во-вторых, между угловыми скобками и словом Атлас есть еще и пробел.

Ну и зачем там еще и обратный слеш - не понял.

$str = '
аатлас
атлас
атласный
"атлас"
Атлас
"Атлас"
Атлас-стрейч
Хан-Атлас
Атлас «Ментенон»
Атлас Ментенон
';
$pattern = '#"?(?<![а-я-]|» )атлас(?![а-я-]| «)"?#iu';
preg_match_all($pattern, $str, $matches);
echo "<pre>" .print_r($matches, true). "</pre>";
Array
(
    [0] => Array
        (
            [0] => атлас
            [1] => "атлас"
            [2] => Атлас
            [3] => "Атлас"
            [4] => Атлас
        )

)

  • 0


#9 Вячеслав

Вячеслав
    Topic Starter
  • Пользователь
  • 357 сообщений
  • Репутация: 0

Отправлено 04 Апрель 2014 - 16:58

вот так тоже не работает (((

'#"?(?<![а-я-]| «)'.$jsArr->title.'(?![а-я-]|» )"?#'

  • 0

#10 matroskin8

matroskin8
  • Пользователь PRO
  • 767 сообщений
  • Репутация: 143

Отправлено 04 Апрель 2014 - 17:11

Я для кого регулярное выражение выше написал и долго расписывал расположение угловых скобок?

Сравните ваш шаблон с моим и найдите разницу... ну или просто возьмите мой шаблон)))


  • 0


robot

robot
  • Пользователь PRO
  • 2 652 сообщений
  • Репутация: 85


Оформление форума – IPBSkins.ru