开发者

How to append or replace trailing question marks using preg_replace?

开发者 https://www.devze.com 2023-01-07 20:33 出处:网络
I want to enforce single question mark at the and of the string. In JavaScript it works perfectly: var re = /[?7!1]*$/;

I want to enforce single question mark at the and of the string. In JavaScript it works perfectly:

var re = /[?7!1]*$/;
document.write('lolwut'.replace(re, '?'));
document.write('lolwut?'.replace(re, '?'));
document.write('lolwut??'.replace(re, '?'));
document.write('lolwut???'.replace(re, '?'));
document.write('lolwut???!!!11'.replace(re, '?'));

All of returned values equals "lolwut?" PHP variant doesnt work that smooth:

$re = '/[?7!1]*$/';
echo preg_replace($re, '?', 'lolwut') . "\n";
echo preg_replace($re, '?', 'lolwut?') . "\n";
echo preg_replace($re, '?', 'lolwut??') . "\n";
echo preg_replace($re, '?', 'lolwut???') . "\n";
echo preg_replace($re, '?', 'lolwut???!!!11') . "\n";

output is:

lolwut?
lolwut??
lolwut??
lolwut??
lolwut??

What i'm doing wrong here?


Update:

$ (Dollar) Assert end of s开发者_JAVA技巧tring

An assertion is a test on the characters following or preceding the current matching point that does not actually consume any characters.

is my confusion here, along with implicit global flag of preg_replace, thanks to salathe for providing a clue. (you guys should vote his answer up, really)


Checkout rtrim() - http://php.net/manual/en/function.rtrim.php

echo rtrim('lolwut','?7!1').'?'; // lolwut?
echo rtrim('lolwut?','?7!1').'?'; // lolwut?
echo rtrim('lolwut??','?7!1').'?'; // lolwut?
echo rtrim('lolwut???!!!11','?7!1').'?'; // lolwut?
echo rtrim('lolwut1??!7!11','?7!1').'?'; // lolwut?

rtrim will Strip whitespace (or other characters) from the end of a string

The second argument:

You can also specify the characters you want to strip, by means of the charlist parameter. Simply list all characters that you want to be stripped. With .. you can specify a range of characters.


Just to answer the question asked ("What i'm doing wrong here?"), you're being confused about what precisely the regular expression matches. With the strings presented, bar the first one, the regex actually matches twice which is why you get two question marks (two matches, two replacements). The root of this behaviour is a mixture of the quantifier (* allows matching nothing) and the end-anchor ($ matches the end of the string).

For lolwut???!!!11:

  • The regex first matches ???!!!11 which is what you expect
  • Giving the string a new value of lulwut?
  • Then it also matches at the point right at the end of the new string
  • Leading to a final replaced value of lulwut??

If you wanted to continue using the same regex with preg_replace then simply restrict it to one replacement by providing a value of 1 to the fourth ($limit) argument:

preg_replace('/[?7!1]*$/', '?', 'lolwut???!!!111', 1);
// limit to only one replacement ------------------^ 

As for a better solution, as the others have said, use rtrim.


You should use the trim function:

echo trim('lolwut???!!!11', '?7!1');

output is:

lolwut
0

精彩评论

暂无评论...
验证码 换一张
取 消