如何使用 preg_replace 附加或替换尾随问号?

发布于 2024-09-10 17:43:59 字数 966 浏览 3 评论 0原文

我想在字符串的 和 处强制使用单个问号。在 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 提供了线索。 (你们真的应该投票赞成他的答案)

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 string
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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

赏烟花じ飞满天 2024-09-17 17:43:59

查看 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 会从字符串末尾去除空格(或其他字符)

第二个参数:

您还可以通过 charlist 参数指定要删除的字符。只需列出您想要删除的所有字符即可。使用 .. 您可以指定字符范围。

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.

迷荒 2024-09-17 17:43:59

只是为了回答所提出的问题(“我在这里做错了什么?”),您对正则表达式确切匹配的内容感到困惑。使用显示的字符串,除了第一个字符串外,正则表达式实际上匹配两次,这就是为什么您会得到两个问号(两次匹配,两次替换)。此行为的根源是量词(* 允许不匹配任何内容)和结束锚点($ 匹配字符串的末尾)的混合。

对于 lolwut???!!!11

  • 正则表达式首先匹配 ???!!!11 这就是您所期望的
  • 给字符串一个新值 lulwut?
  • 那么它也会匹配新字符串末尾的点
  • ,导致最终替换值 lulwut??

如果您想继续使用与 相同的正则表达式>preg_replace 然后通过为第四个 ($limit) 参数提供值 1 来将其限制为一个替换:

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

至于更好的解决方案,因为其他人说过,使用rtrim

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.

南烟 2024-09-17 17:43:59

您应该使用修剪功能:

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

输出为:

lolwut

You should use the trim function:

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

output is:

lolwut
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文