preg_replace 一次替换多个模式

发布于 2024-11-18 01:41:38 字数 459 浏览 2 评论 0原文

我有几个替换可以应用于我的 $subject,但我不想让旧替换 #(1 .. i-1) 的输出与当前替换 #i 匹配。

$subject1 = preg_replace($pat0, $rep0, $subject0);
$subject2 = preg_replace($pat1, $rep1, $subject1);
$subject3 = preg_replace($pat2, $rep2, $subject2);

我尝试使用一个带有数组的 preg_replace 来进行模式和替换,希望它能立即完成;但事实证明,这只不过是连续调用简单的 preg_replace (当然还有一些优化)。

在我阅读了 preg_replace_callback 后,我想这不是一个解决方案。

有什么帮助吗?

I have few substitutions to apply on my $subject but I don't want to allow the output from old substitutions #(1 .. i-1) to be a match for the current substitution #i.

$subject1 = preg_replace($pat0, $rep0, $subject0);
$subject2 = preg_replace($pat1, $rep1, $subject1);
$subject3 = preg_replace($pat2, $rep2, $subject2);

I tried using one preg_replace with arrays for patterns and replacement hoping that it make it at once; but it turned out to be not more than calling the simple preg_replace successively (with some optimization of course)

After I read about preg_replace_callback, I guess it is not a solution.

Any help?

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

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

发布评论

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

评论(2

奢望 2024-11-25 01:41:38

使用回调,您可以使用捕获组来检测匹配的模式,例如 (?:(patternt1)|(pattern2)|(etc),仅定义匹配的模式捕获组 。

唯一的问题是您当前的捕获组将被转移。要修复(阅读解决方法),您可以使用命名组(分支重置(?|(foo)|(bar)) 可以工作(如果您的版本支持),但是然后您必须使用其他方式检测哪个模式匹配。)

示例

function replace_callback($matches){
    if(isset($matches["m1"])){
        return "foo";
    }
    if(isset($matches["m2"])){
        return "bar";
    }
    if(isset($matches["m3"])){
        return "baz";
    }
    return "something is wrong ;)";
}

$re = "/(?|(?:regex1)(?<m1>)|(?:reg(\\s*)ex|2)(?<m2>)|(?:(back refs) work as intended \\1)(?<m3>))/";

$rep_string = preg_replace_callback($re, "replace_callback", $string);

未测试(此处没有 PHP),但类似的方法可以工作。

Use a callback, you can detect which pattern matched by using capturing groups, like (?:(patternt1)|(pattern2)|(etc), only the matching patterns capturing group(s) will be defined.

The only problem with that is that your current capturing groups would be shifted. To fix (read workaround) that you could use named groups. (A branch reset (?|(foo)|(bar)) would work (if supported in your version), but then you'd have to detect which pattern has matched using some other way.)

Example

function replace_callback($matches){
    if(isset($matches["m1"])){
        return "foo";
    }
    if(isset($matches["m2"])){
        return "bar";
    }
    if(isset($matches["m3"])){
        return "baz";
    }
    return "something is wrong ;)";
}

$re = "/(?|(?:regex1)(?<m1>)|(?:reg(\\s*)ex|2)(?<m2>)|(?:(back refs) work as intended \\1)(?<m3>))/";

$rep_string = preg_replace_callback($re, "replace_callback", $string);

Not tested (don't have PHP here), but something like this could work.

三寸金莲 2024-11-25 01:41:38

在我看来,preg_replace_callback是最直接的解决方案。您只需使用 | 运算符指定替代模式,并在回调中编写 ifswitch 即可。对我来说似乎是正确的方式。你为什么丢弃它?

另一种解决方案是临时替换特殊字符串。说:

// first pass
$subject = preg_replace($pat0, 'XXX_MYPATTERN0_ZZZ', $subject);
$subject = preg_replace($pat1, 'XXX_MYPATTERN1_ZZZ', $subject);
$subject = preg_replace($pat2, 'XXX_MYPATTERN2_ZZZ', $subject);
// second pass
$subject = preg_replace("XXX_MYPATTERN0_ZZZ",$rep0 , $subject);
$subject = preg_replace("XXX_MYPATTERN1_ZZZ",$rep1 , $subject);
$subject = preg_replace("XXX_MYPATTERN2_ZZZ",$rep2 , $subject);

这非常丑陋,不能很好地适应动态替换,而且也不是万无一失的,但对于某些“运行一次”的脚本来说可能是可以接受的。

It seems to me that preg_replace_callback is the most direct solution. You just specify the alternate patterns with the | operators and inside the callback you code an if or switch. Seems the right way to me. Why did you discard it?

An alternative solution is to make a temporary replace to a special string. Say:

// first pass
$subject = preg_replace($pat0, 'XXX_MYPATTERN0_ZZZ', $subject);
$subject = preg_replace($pat1, 'XXX_MYPATTERN1_ZZZ', $subject);
$subject = preg_replace($pat2, 'XXX_MYPATTERN2_ZZZ', $subject);
// second pass
$subject = preg_replace("XXX_MYPATTERN0_ZZZ",$rep0 , $subject);
$subject = preg_replace("XXX_MYPATTERN1_ZZZ",$rep1 , $subject);
$subject = preg_replace("XXX_MYPATTERN2_ZZZ",$rep2 , $subject);

This is very ugly, does not adapt well to dynamic replacements, and it's not foolproof, but for some "run once" script it might be acceptable.

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