Chameron
Chameron

Reputation: 2974

php - regexp - multi match result

string string {format mat=34/} string string string string string string string string 

string string {format mat=34/} string string string string string string string string 
  1. $pattern = "/{format[a-z0-9=\s]*\/}/i";

    str_replace($pattern, 'test', $strings);

    it will replace all formats in string, i want to replace only first "format", and remove all another "format". How ?

  2. when get match result is "{format mat=34/}". i want to find string begin with "mat=".

So i have this

$string = "{format mat=34/}";
$pattern = "/^mat=[0-9]*/"; // result is null
$pattern = "/mat=[0-9]*/"; // ok, but also effect with "{format wrongformat=34/}"

How to match string that begin with "mat="

Upvotes: 1

Views: 161

Answers (4)

Maxime Pacary
Maxime Pacary

Reputation: 23061

For your first question, you could use some kind of str_replace_once()

Example found in PHP manual comments:

function str_replace_once($str_pattern, $str_replacement, $string)
{ 
  if (strpos($string, $str_pattern) !== false)
  {
    $occurrence = strpos($string, $str_pattern);
    return substr_replace($string, $str_replacement, strpos($string, $str_pattern), strlen($str_pattern));
  }
  return $string;
} 

To remove all other matches, see Sergej's answer :)

For your second question:

$string = '{format mat=34/}';
preg_match("|\s(mat=[0-9]+)/\}$|", $string, $matches);
print_r($matches); // $matches[1] contains 'mat=34'

Upvotes: 0

Sergej Brazdeikis
Sergej Brazdeikis

Reputation: 1373

Here is your solution:

$string  = "string {format mat=34/} string string string {format mat=34/} string string string string {format mat=34/} string string string string string ";

// replace first match with 'test'
$string = preg_replace('/\{format mat=[\d]*\/\}/', 'test', $string, 1);

// remove all other matches
$string = preg_replace('/\{format mat=[\d]*\/\}/', '', $string);

Upvotes: 1

Doug T.
Doug T.

Reputation: 65629

(for the first part of your question)

You could match the first format with this regex, which uses {n} to specify only matching the first occurence

  $pattern = "(^.*?\{format[a-z0-9=\s]*\}.){1}"

Starts from the first character, does a non-greedy match until the first format, then takes exactly {1} occurence of that.

Run this through to do your initial replace, and then afterwords do a normal str_replace on the rest of the formats.

Upvotes: 1

Alex Netkachov
Alex Netkachov

Reputation: 13532

  1. not str_replace, but preg_replace, $limit parameter of preg_replace limits number of replaces - just set it to 1.
  2. use \b - word boundary.

    $pattern = '/\bmat=[0-9]*/';

Upvotes: 0

Related Questions