【问题标题】:Regex to replace all matches unless the match is at the end of the string正则表达式替换所有匹配项,除非匹配项位于字符串的末尾
【发布时间】:2013-01-21 21:19:17
【问题描述】:

我目前正在使用此正则表达式替换字符串中的所有非字母数字字符并用破折号替换它们

$newString = preg_replace("/[^a-z0-9.]+/i", "-", $string);

工作正常以下字符串。

$string = "this will work fine";
$newString = "this-will-work-fine";

但是如果字符串有一个非字母数字作为最后一个字符,它将匹配并替换它,正如人们所怀疑的那样。

$string = "How can I fix this?";
$newString = "How-can-I-fix-this-";

我如何改进这个正则表达式以获得以下输出?

$newString = "How-can-I-fix-this";

正则表达式应该适用于两种情况。我知道我可以使用单独的函数修剪字符串,但理想情况下我想使用一个正则表达式。这可能吗?

【问题讨论】:

  • 大多数正则表达式实现不允许您定义不同的替换字符串。您通常创建一个模式,然后给出一个(单个!)替换字符串。那么,问题是,您使用的是什么语言(正则表达式实现)?
  • 我正在使用php的preg_replace函数
  • 第三种情况呢?什么时候开头有非单词字符?
  • @Salman - 请参阅我对第三种情况的 one 正则表达式解决方案的回答。

标签: php regex string preg-replace


【解决方案1】:

您可以随时trim("-how-can-i-fix-this-", "-");

【讨论】:

    【解决方案2】:

    由于您使用的是 PHP,因此您可以一次性定义多个模式和替换。这是一个快速演示:

    $string = "How can I fix this?";
    $patterns = array('/[^0-9a-z.]+/i', '/[^0-9a-z.]+(?=$)/i');
    $replacements = array('-', '');
    
    echo preg_replace($patterns, $replacements, $string) . "\n";
    

    哪个打印:

    我该如何解决这个问题

    其实无非就是连续两次替换:

    $string = "How can I fix this?";
    
    echo preg_replace('/[^0-9a-z.]+/', '-', preg_replace('/[^0-9a-z.]+$/', '', $string)) . "\n";
    

    【讨论】:

    • 我几乎会在第二种模式中使用/\W+$/,而不是使用前瞻(尽管任何一种都可以)。
    • @BradChristie,是的,看起来更好。
    • \W+ 不起作用。您必须将[^a-z0-9.]+i 开关或[^a-zA-Z0-9.]+ 一起使用。 \W+ 不匹配 _ 但匹配 .。这不是 OP 想要的。
    • 而且\W 不匹配_ ;-)
    【解决方案3】:

    我认为您必须分两步执行此操作,因为您有两种不同的情况:在字符串的开头和中间,您想用'-'替换非字母数字。最后,你想用空字符串替换它们。

    【讨论】:

    • 这就是我要建议的。并非所有内容都必须塞进一个正则表达式中。
    【解决方案4】:

    实际上,可以在一个正则表达式中完成:

    $newString = preg_replace('/[^a-z0-9.]++([a-z0-9.]++)(?:[^a-z0-9.]++$)?/i', '-$1', $string);

    注意:

    • 供将来参考,'-\1''-\\1'"-\\1""-$1" 都是替换字符串的有效替代项。
    • 在这种情况下,所有格量词并不是必需的。但是,即使速度提升微乎其微,我也总是使用它们。

    编辑:

    第三种情况(第一个字符不是字母数字)也可以用一个正则表达式来完成:

    $newString = preg_replace('/(?:^[^a-z0-9.]++([a-z0-9.]++))?[^a-z0-9.]++([a-z0-9.]++)(?:[^a-z0-9.]++$)?/i', '$1-$2', $string);

    【讨论】:

    • 这似乎不起作用.. $string="这会起作用吗?";评估为“将——”
    • @Alex - 很有趣。您是否尝试将所有++ 替换为+?我可能应该提到我没有在 PHP 中测试正则表达式,只是在我的文本编辑器中。
    • 我没有在 PHP 中进行测试,我正在使用一个名为“patterns”的 OSX 正则表达式应用程序。您最近的更改没有运气
    • @Alex - 我刚刚在RegexPlanet 尝试了正则表达式[^a-z0-9.]++([a-z0-9.]++)(?:[^a-z0-9.]++$)? 替换-$1。在那里工作得很好。
    • 我会再次检查并让您知道。感谢您的帮助
    【解决方案5】:
    $string = 'How can I fix this?';
    $string = trim(preg_replace('/[^A-Za-z0-9]/', '-', $string), '-'); 
    

    将所有非字母数字替换为'-',然后从末端修剪。

    【讨论】:

      猜你喜欢
      • 2016-11-04
      • 1970-01-01
      • 1970-01-01
      • 2019-12-18
      • 1970-01-01
      • 2016-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多