John Doe Smith
John Doe Smith

Reputation: 1643

Wrap first word in <b> tag with preg_replace -- can't reference fullstring match

I generated the following regex code with http://gskinner.com/RegExr/ where it works, but when I execute it with PHP, it fails to use the match in the replacement string.

preg_replace(
    '/(?<=\>)\b\w*\b|^\w*\b/',
    '<b>$&</b>',
    'an example'
);

Output:

<b>$&</b> example

Expected:

<b>an</b> example

I know that obviously the $& is not doing the correct thing, but how can I get it to work?

Upvotes: 4

Views: 5655

Answers (4)

mickmackusa
mickmackusa

Reputation: 47894

Yes, $& will work well in javascript when using the fullstring match in the replacement string, but not in all languages/environments.

In PHP, you can more intuitively access matches and capture groups with a $ followed by 0 for the fullstring match or incremented integers for every subsequent capture group.

Your pattern can be refined in PHP as well. \K restarts the fullstring match so you can avoid the performance cost of a lookbehind.

New code:

preg_replace(
    '/(?:^|\>\K)\w+/',
    '<b>$0</b>',
    $string
);

This pattern says match the start of the string or immediately after a backslash then a greater than symbol. Then greedily match one or more word characters (A-Z, a-z, 0-9, _). The leading word boundary is not needed because the leading anchor and character rules perform the same assurance as the word boundary. The trailing word boundary is not necessary because the \w will halt matching before the first encountered non-word chatacter.

The replacement parameter will wrap the whole match in bold tag HTML markup.

Upvotes: 1

Timm
Timm

Reputation: 12753

Try with this instead

preg_replace('/(?<=\>)\b\w*\b|^\w*\b/', '<b>$0</b>', $string);

$0 means it will become the first thing matched in your regex, $1 will become the second etc.

You could also use back-references; \0 gets the first thing matched back from where you are, \1 gets the second thing matched back etc. More Info

Upvotes: 10

flowfree
flowfree

Reputation: 16462

$string = 'an example';
echo preg_replace('/^\b(.+?)\b/i', '<b>$1</b>', $string);

// <b>an</b> example

Upvotes: 1

DhruvPathak
DhruvPathak

Reputation: 43235

You need to put a number after $ to refer to grouped part of the regex.Here it would be first group , hence 0. Working example here : http://codepad.org/4V7GWdja

<?php

$string = "an example";
$string = preg_replace('/(?<=\>)\b(\w*)\b|^\w*\b/', '<b>$0</b>', $string);
var_dump($string);

?>

Upvotes: 2

Related Questions