Reputation: 683
Given the following string and regular expression, the resulting behavior is something I don't understand. preg_match delivers what I am expecting while preg_replace doesn't make sense to me.
$string = 'aaa [Ticket#RS-123456] äüö [xxx] ccc ddd';
$re = '@(.*)?(\[Ticket\#)(.*)(\])(.*)?@siU';
What I finally need in this example is the string RS-123456 (or whatever string would be at this position). This string should match at the 3rd position ($3), if I don't completely misunderstand regular expressions.
preg_match($re, $string, $matches_pm);
Result (as expected):
Array(
[0] => aaa [Ticket#RS-123456]
[1] => aaa
[2] => [Ticket#
[3] => RS-123456 // That's exactly what I would expect
[4] => ]
)
$res_pr = preg_replace($re, "$3", $string);
Result (unexpected):
RS-123456 äüö [xxx] ccc ddd
I hope anyone can open my eyes and show me where my logical failure is hiding.
Upvotes: 2
Views: 296
Reputation: 627022
Both match the same text, but preg_match
returns the first match only while preg_replace
replaces the match (that is not the entire string) with Group 3 contents leaving äüö [xxx] ccc ddd
in the resulting string.
Use
$re = '@(.*)(\[Ticket\#)(.*?)(\])(.*)@si';
to get the same results with preg_match
and preg_replace
.
See the PHP demo.
However, preg_match
is the preferred way here:
if (preg_match('@\[Ticket#\K[^]]+@i', $string, $matches_pm)) {
echo $matches_pm[0];
}
See this PHP demo.
Pattern details
\[Ticket#
- a literal [Ticket#
substring\K
- match reset operator discarding the currently matched text[^]]+
- 1 or more chars other than ]
Upvotes: 2