我想在字符串和字符串处强制执行单个问号。在JavaScript中它完美地运作:
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, '?'));
所有返回的值等于“lolwut?” PHP变体不能顺利运行:
$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";
输出是:
lolwut?
lolwut??
lolwut??
lolwut??
lolwut??
我在这里做错了什么?
更新
$(美元)断言字符串的结尾
断言是对当前匹配点之后或之前的字符的测试,实际上不消耗任何字符。
这里是我的困惑,以及preg_replace的隐含全局标志,感谢 salathe 提供线索。 (你们应该投票给他们的答案,真的)
答案 0 :(得分:7)
结帐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将Strip whitespace (or other characters) from the end of a string
第二个论点:
您还可以通过charlist参数指定要删除的字符。只需列出要删除的所有字符。使用..,您可以指定一系列字符。
答案 1 :(得分:4)
只是回答问题(“我在这里做错了什么?”),你对正则表达式匹配的精确感到困惑。使用字符串,禁止第一个,正则表达式实际匹配两次这就是为什么你得到两个问号(两个匹配,两个替换)。这种行为的根源是量词的混合(*
允许不匹配)和结束锚($
匹配字符串的结尾)。
lolwut???!!!11
:
???!!!11
,这是您所期望的lulwut?
lulwut??
如果您想继续使用与preg_replace
相同的正则表达式,则只需将1
的值提供给第四个($limit
)参数,即可将其限制为一个替换:
preg_replace('/[?7!1]*$/', '?', 'lolwut???!!!111', 1);
// limit to only one replacement ------------------^
至于其他人所说的更好的解决方案,请使用rtrim。
答案 2 :(得分:1)
你应该使用修剪功能:
echo trim('lolwut???!!!11', '?7!1');
输出是:
lolwut