Автолинк слова в строке, если они существуют в массиве - PullRequest
0 голосов
/ 18 января 2019

У меня есть массив слов и ссылок, подобных этой (отсортированы по длине):

$replacement = array = [
    'another example' => 'http://another-example.com',
    'examples' => 'http://examples.com',
    'example' => 'http://example.com',
];

И у меня есть такой текст:

$content = "Two examples are the combination of an example and another example.";

Я хочу заменить слова ссылками на ключевые слова, которые приведут к следующему результату:

Two <a href="http://examples.com">examples</a> are the combination of an <a href="http://example.com">example</a> and <a href="http://another-example.com">another example</a>.

Итак, мой подход состоит в том, чтобы отсортировать массив ключевых слов по длине и заменить ключ для значения и, как-то так, избежать сценария для замены слов в ссылке (текст привязки и атрибут href) ... проблема это ... как избежать замены по ссылке?

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

Ответы [ 3 ]

0 голосов
/ 18 января 2019

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

foreach ($replacement as $orig => $sub) {
    $replacement[$orig] = '<a href="'.$sub.'">'.$orig.'</a>';
}

/* So now $replacement looks like this:
array(3) {
    ["another example"]=>
        string(56) "<a href="http://another-example.com">another example</a>"
    ["examples"]=>
        string(42) "<a href="http://examples.com">examples</a>"
    ["example"]=>
        string(40) "<a href="http://example.com">example</a>"
}
*/

$content = strtr($content, $replacement);

EDIT:

Если вам нужны точные совпадения слов, вам понадобятся регулярные выражения. Вот как я бы попытался это сделать:

$content = "Two examples are the combination of an example and another example.";

$replacement = array(
    'another example' => 'http://another-example.com',
    'examples' => 'http://examples.com',
    'example' => 'http://example.com',
);
$new_replacement = array();

foreach ($replacement as $orig => $sub) {
    $new_replacement['/\b'.$orig.'\b/'] = '<a href="'.$sub.'">'.$orig.'</a>';
}

$orig = array_keys($new_replacement);
$sub = array_values($new_replacement);

$content = preg_replace($orig, $sub, $content, 1);

echo $content;
0 голосов
/ 18 января 2019

Вам необходимо использовать preg_replace с \b. Это ограничит замену полными словами.
Я использую implode для построения шаблона регулярных выражений, чтобы он выглядел как:

"\b(another example)|(examples)|(example)\b/"

Затем замена использует то, что фиксирует регулярное выражение.

$replacement = [
    'another example' => 'http://another-example.com',
    'examples' => 'http://examples.com',
    'example' => 'http://example.com',
];

$content = "Two examples are the combination of an example and another example.";

echo preg_replace("/\b(". implode(")|(", array_keys($replacement)) . ")\b/", "<a href=\"$0\">$0</a>", $content);

Выход:

Two <a href="examples">examples</a> are the combination of an <a href="example">example</a> and <a href="another example">another example</a>.

https://3v4l.org/1Jhak


Чтобы получить бонус для работы, нам нужно использовать четвертый аргумент preg_replace и зациклить массив.
Это ограничивает preg_replace только одной заменой.

$replacement = [
    'another example' => 'http://another-example.com',
    'examples' => 'http://examples.com',
    'example' => 'http://example.com',
];

$content = "Two examples are the combination of an example and another example, 
Two examples are the combination of an example and another example.";


foreach($replacement as $find => $repl){
    $content =  preg_replace("/\b(". $find . ")\b/", "<a href=\"$repl\">$0</a>", $content, 1);
}
echo $content;

Выход:

Two <a href="http://examples.com">examples</a> are the combination of an <a href="http://example.com">example</a> and <a href="http://another-example.com">another example</a>, 
Two examples are the combination of an example and another example.

https://3v4l.org/8GFZr

0 голосов
/ 18 января 2019

Вы можете попробовать strtr .

Если задано два аргумента, вторым должен быть массив в виде массива ('from' => 'to', ...). Возвращаемым значением является строка, в которой все вхождения ключей массива были заменены соответствующими значениями. Самые длинные ключи будут опробованы первыми. Как только подстрока заменена, ее новое значение не будет снова найдено .

$content = strtr($content, $replacement);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...