1

我想在某些单词中选择并用空格(“”)替换破折号/连字符(“-”)(例如:“start-down”更改为“start down”),同时忽略其他单词的替换(例如: “启动”保持“启动”)使用 PHP 的 preg_replace()。

这是我想出的正则表达式:

(?<!(start))-(?!(up))|(?<!(start))-|-(?!(up))

在此数据上使用上述正则表达式:

  1. 启动
  2. 开始
  3. 万事如意
  4. 停下
  5. 开始
  6. 停顿

返回以下内容:

  1. 启动
  2. 开始
  3. 有什么事
  4. 停下
  5. 开始

它非常适合启动。但我知道以后我需要在列表中添加其他例外情况,例如停止(例如:“停止”保持“停止”)。

所以问题是这样的:我是否应该通过 PHP 的函数(例如 str_replace() 和 if else/switch case 使用一组“不可更改的”单词)来执行此操作,循环遍历这些并在必要时进行适当的更改,或者是否有正则表达式中的方法如果选择是某个单词的一部分,则忽略某些选择?

4

2 回答 2

3

我的 php 有点生锈,但这是我的建议:

function do_replace($m) {
    return strlen($m[1]) > 0 ? $m[1] : ' ';
}

preg_replace_callback('/(start-up|stop-off)|-/', 'do_replace', $input);

如果你的 PHP 版本支持匿名函数,你可以这样做:

preg_replace_callback(
    '/(start-up|stop-off)|-/',
    function($m) {
        return strlen($m[1]) > 0 ? $m[1] : ' ';
    },
    $input
);

这种方法的真正好处是它很容易扩展到您想要排除的任意数量的“特殊词”。

于 2013-06-26T17:16:06.867 回答
1

您可以将模式重置 ( \K) 技巧与 preg_replace 一起使用,例如:

$input = 'passe-montagne, passe-partout, passe-murail, start-up, stop-off';

echo preg_replace('~\b(?>start-up|stop-off)\b\K|-~', ' ', $input);

检查之前\K的所有内容,但从匹配结果中排除。

注意:使用这种技巧,您的模式可以更有效:

~\bst(?>art-up|op-off)\b\K|-~
于 2013-06-26T17:26:57.727 回答