James
James

Reputation: 33

foreach with preg_replace only outputting 1 result

I'm having a problem with foreach and preg_replace(). I have a string of text and would like to use preg_replace() to extract all words that come after the @ symbol and then create an array which I can then use to submit each value into the database.

At the moment only the first result is being outputted. Could you help me to resolve this issue please? :)

<?php
$status['message'] = 'Hello I would like to tag @james and @bob and @barry';
preg_match('/(?<=@)\S+/i', $status['message'], $match);

foreach($match as $tag) {
    // insert each result into database
    echo $tag;
}
?>

Upvotes: 1

Views: 62

Answers (2)

Sverri M. Olsen
Sverri M. Olsen

Reputation: 13283

Well, preg_match() only spits out the first result. After finding the first result it stops. If you read the documentation then you would know that.

If you want to get all the matches then you have to use preg_match_all().

Your regular expression is also not very well thought out. It will match just about anything (including invalid tags), as long as it does not contain whitespace characters. For example, something like @@!"#¤% will be matched...

When writing regular expressions it is generally a good idea to always be as restrictive as possible. In other words, it should only match what you need; using wildcard stuff like \S+, which matches everything except a handful of characters, is rarely a good idea.

Something like this would be an improvement. It will, however, match stuff that maybe should not be matched (like @user in @@user~).

$regex = '/(?<=@)[a-zA-Z0-9_]+/';

Upvotes: 0

Kevin
Kevin

Reputation: 41873

Use preg_match_all instead:

— Perform a global regular expression match

$status['message'] = 'Hello I would like to tag @james and @bob and @barry';
preg_match_all('/(?<=@)\S+/i', $status['message'], $match);

foreach(reset($match) as $tag) {
    // insert each result into database
    echo $tag . '<br/>';
}

Upvotes: 2

Related Questions