views:

466

answers:

5

Hi, I have an array with words like

$arr = array("go", "walk", ...)

I would like to replace these words with links f they are matched in sentences. But it should be only if they match exactly (for example "walk" should match "Walk" or "walk!" but not also "walking")

And the replacement should be a simple link like: < a href='#walk' >walk< /a >

Anybody Any idea?

+4  A: 

To Match each words like "walk" but not "walking" Use \b for word bounday.

For Example, "\bwalk\b"

S.Mark
I tried this example :<?php$pattern = "\bwalk\b";$replacement = "wwalk";$text = "I do walk. I am walking. Let me walk!";echo preg_replace( $pattern, $replacement, $text);?>But I get:Warning: preg_replace(): Delimiter must not be alphanumeric or backslash
Granit Luzhnica
You need delimiters on your pattern like $pattern = "/\bwalk\b/i". The i quantifier makes it case insensitive.
Residuum
Thank you very much!
Granit Luzhnica
A: 

Try something like this:

$words = array('walk','talk');

foreach($words as $word)
{
    $word = preg_replace("/\b$word\b/","< a href='#$word' >$word< /a >",$word);
}
codaddict
A: 

Your examples are quite specific, so it's hard to know exactly what you need to match in practice (e.g. do you want to include the '!' in the link?), but try this:

<?php

$text = "Walk! I went for a walk today. I like going walking. Let's go walk!";
$needles = array('go', 'walk');

foreach ($needles as $needle)
  $text = preg_replace('/\b(' . $needle . ')\b/i', '<a href="#' . $needle . '">$1</a>', $text);

print $text;
Alf Eaton
+2  A: 
function magicWords($words, $string) {
  $from = $to = array();
  foreach($words as $word) {
    $from[] = "/\b$word\b/i"; // \b represents a word boundary
    $to[] = '<a href="#' . strtolower($word) . '">${0}</a>';
  }

  return preg_replace($from, $to, $string);

}

$words = array('go', 'walk');

echo magicWords($words, "Lets go walking on a Walk");

This outputs:

'Lets <a href="#go">go</a> walking on a <a href="#walk">Walk</a>.'

Note that it matches "go", and "walk", but not "walking", and maintains the capital W on Walk while the link becomes lower case "#walk".

This way, "Walk walk WALK wALk" will all link to #walk without affecting the original formatting.

meagar
A: 

I think the following might be what you want.

<?php
$someText = 'I don\'t like walking, I go';
$words = array('walk', 'go');
$regex = '/\\b((' . implode('|',$words) . ')\\b(!|,|\\.|\\?)?)/i';
echo preg_replace_callback(
    $regex,
    function($matches) {
        return '<a href=\'' . strtolower($matches[2]) . '\'>' . $matches[1] . '</a>';
    },
    $someText);
?>

A few of points though:

  • This solution and all the others will match any occurrences of the word be they in element attributes or whatever
  • I've added a bit on the end for punctuation matching should you want to include it within the link/anchor tags.
  • This requires php 5.3 anonymous functions. I tought this was an interesting alternative to the foreach methods mentioned
bearver