1

I'm using a PHP script to link each word of the string:

<?
$str = "hello<br> guys good man";
$arr = explode(' ', $str);
foreach($arr as $value){
    echo '<a href="http://www.dumbsearch.com/now/searchcompleted.php?q='.$value.'">'.$value.'</a>';
}
?>

How do I link each word of the string $str without linking the <br>s?

j0k
  • 22,600
  • 28
  • 79
  • 90
  • Why do you duplicate questions? http://stackoverflow.com/questions/14269595/place-each-word-in-a-link-php I have already answered you in the comment of the correct answer – Glavić Jan 11 '13 at 00:57

7 Answers7

8

You can just use preg_replace

// More complext string
$str = "hello<br> guys good man <a href=\"http://google.com\">Google</a> <br /> hurry";

// Url Template
$template = '<a href="http://www.dumbsearch.com/now/searchcompleted.php?q=%1$s">%1$s</a>';

// Replace Words
echo preg_replace("/(?!(?:[^<]+>|[^>]+<\/a>))\b([a-z]+)\b/is", sprintf($template, "\\1"), $str);

Output

<a href="http://www.dumbsearch.com/now/searchcompleted.php?q=hello">hello</a>
<br>
<a href="http://www.dumbsearch.com/now/searchcompleted.php?q=guys">guys</a>
<a href="http://www.dumbsearch.com/now/searchcompleted.php?q=good">good</a>
<a href="http://www.dumbsearch.com/now/searchcompleted.php?q=man">man</a>
<a href="http://google.com">Google</a>
<br />
<a href="http://www.dumbsearch.com/now/searchcompleted.php?q=hurry">hurry</a>
Baba
  • 94,024
  • 28
  • 166
  • 217
  • Great answer, can you just clarify the need for the `sprintf` related code? – Gras Double Jan 13 '13 at 22:20
  • @DoubleGras I do not want to concatenate the value twice and also its more also old habits die hard see why : http://stackoverflow.com/questions/1386593/why-use-sprintf-function-in-php – Baba Jan 13 '13 at 22:33
  • Gotcha. It's just a bit of modularity, so you can feed the template by a lot of methods without touching it. – Gras Double Jan 13 '13 at 22:49
  • Something like that .... :) see PHP doc for more information http://php.net/manual/en/function.sprintf.php – Baba Jan 13 '13 at 22:51
2

Use the strip_tags() function before/in your explode:

$arr = explode (' ', strip_tags($str));
JvO
  • 3,036
  • 2
  • 17
  • 32
2

Untested, but start with JvO's code and put the links back into the original string:

$str = "hello<br> guys good man";
$arr = explode (' ', strip_tags($str));
foreach($arr as $value) {
    $link = '<a href="http://www.dumbsearch.com/now/searchcompleted.php?q='.$value.'">'.$value.'</a>';
    $str = str_replace($value, $link, $str);
}
echo $str;

Note that you can save time by removing duplicates from $arr.

Edit: in fact, you must remove duplicates from $arr, or things will get ugly:

$arr = array_unique(explode (' ', strip_tags($str)));

... and another edit to the original code for an error.

Jerry
  • 3,391
  • 1
  • 19
  • 28
  • can you be more specific? What happens? – Jerry Jan 11 '13 at 01:15
  • just echoes the original. :( without the links ect –  Jan 11 '13 at 01:16
  • d'oh! $str = str_replace(...) – Jerry Jan 11 '13 at 01:17
  • no it doesn't work. :( Even when I use arry unique, it's completely messy and disoddard and nothing looks right. :( (Note that I'm dealing with some weird characters in my string, maybe that could be causing it, but i want that fixed), thanks!;) –  Jan 11 '13 at 01:44
  • Yeah, ultimately I think this approach will be too flakey. If 'search' is in the original string, things will really go haywire. It's possible to work around all that stuff, but if you first create the array with explode(), then hellohellosharp above has a better solution. It will have problems also if there are more complicated tags besides just
    , but but otherwise seems perfectly fine. For a more bulletproof solution, preg_match() and preg_replace() are the right tools for the job.
    – Jerry Jan 11 '13 at 02:37
  • Yeah, but even hellohellosharps answer was messy a lot of the time... :( So I decided that it was better to just replace the `
    `s with spaces...
    –  Jan 11 '13 at 02:45
1

Before you form the link, process the string first:

$proc_val = preg_replace('/<br>/', '', $value);
echo '<a href="http://foo.php?q='.$proc_val.'">'.$value.'</a>';
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
1

Not sure what you were saying in the comment of Jvo's answer, but you can always use the striptags in the foreach as well and only strip the link part.

foreach($arr as $value){
    echo '<a href="http://www.dumbsearch.com/now/searchcompleted.php?q='.strip_tags($value).'">'.$value.'</a>';
}

So here is the full code:

<?
$str = "hello<br> guys good man";
$arr = explode(' ', $str);
foreach($arr as $value){
    echo '<a href="http://www.dumbsearch.com/now/searchcompleted.php?q='.strip_tags($value).'">'.$value.'</a>';
}
?>

You really should think about what explode(' ', $str) is going to do though.

Any time any HTML tag has attributes to it like <span style="color: red;"> you are going to run into trouble. You should strip_tags first, on the entire string, then process it. Keep an HTML version as a separate string if you need to add stuff later.

kmoney12
  • 4,413
  • 5
  • 37
  • 59
  • but then how do I retain the `br`s in the echoed result? –  Jan 11 '13 at 01:06
  • The first code part of my answer will strip the tags from the URL but keep them in the part that actually displays. Look at this part of it: `searchcompleted.php?q='.strip_tags($value).'">'.$value.'';` – kmoney12 Jan 11 '13 at 01:09
  • But it displayed this: Fatal error: Call to undefined function striptags() in /home/content/76/7290476/html/dumbocr/post.php on line 111 –  Jan 11 '13 at 01:17
  • Found the problem, missing an underscore in the striptags function. You might want to edit your original answer. Thanks so much! it works now! –  Jan 11 '13 at 01:19
  • The resulted text looks ugly, ie linebreaks everywhere inside links, many words linked to the same word ect. :( –  Jan 13 '13 at 16:41
1

Why not just explode the string as you currently are and simply strip the tags in the URL.

$str = "hello<br> guys good man";
$arr = explode(' ', $str);
foreach($arr as $value){
    echo '<a href="http://www.dumbsearch.com/now/searchcompleted.php?q='.strip_tags($value).'">'.$value.'</a>';
}

This will output the following HTML which is what I believe you want.

<a href="http://www.dumbsearch.com/now/searchcompleted.php?q=hello">hello<br></a>
<a href="http://www.dumbsearch.com/now/searchcompleted.php?q=guys">guys</a>
<a href="http://www.dumbsearch.com/now/searchcompleted.php?q=good">good</a>
<a href="http://www.dumbsearch.com/now/searchcompleted.php?q=man">man</a>
PassKit
  • 12,231
  • 5
  • 57
  • 75
0

If the string is quite long, and can contain any number of tags, including <p>, <h1> and <br> as well as the more correct <br/>, you could consider parsing the lot, and use str_replace:

$string = 'Foo<br/>Hello Bar!';
$DOM = new DOMDocument;
//make sure all breaks are preceded by a space, if not words might be concatenated by accident
$DOM->loadHTML(str_replace('<br', ' <br', $string));
//get all nodes
$nodes = $DOM->getElementsByTagName('*');
//get the text, split it and replace, but keep track of replaced words
$replaced = array();
for ($i = 0, $j = $nodes->length; $i<$j;$i++)
{
    $words = explode(' ',$nodes->item($i)->nodeValue);
    while($word = array_shift($words))
    {
        if (!array_key_exists($word, $replaced))
        {//avoid replacing twice (and thus creating a link within a link)
             $replaced[$word] = true;
             $string = str_replace($word, '<a href="http://www.dumbsearch.com/now/searchcompleted.php?q='.urlencode($word).'">'.$word.'</a>', $string);
        }
    }
}

This code is tested and working.

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149