【问题标题】:Replace All matching string only at start仅在开始时替换所有匹配的字符串
【发布时间】:2013-06-23 03:12:04
【问题描述】:

我想替换字符串开头的所有匹配项。 这是一个用例。 www.example.com/example.com/http://example.com/www.abc.com/www.example.com/xyz.com/example.com 应该成为 www.abc.com/www.example.com/xyz.com/example.com

应该删除每个匹配的匹配项,直到遇到不匹配的字符串。

我正在使用preg_replace,目前我有这个正则表达式

'/(http:\/\/){0,1}(www.){0,1}example.com(\/)*/i' 问题是它会替换所有匹配的字符串。

我只想在开始时替换匹配的字符串,如果匹配失败一次,它不应该替换任何东西。 有什么帮助建议吗?

谢谢。

【问题讨论】:

    标签: php regex preg-replace


    【解决方案1】:

    使用^ 锚确保它只匹配字符串的开头:

    '/^(http:\/\/){0,1}(www.){0,1}example.com(\/)*/i'
    

    要了解更多关于锚点的信息,请查看this regex tutorial

    注意:在正则表达式中,?{0,1} 相同。

    【讨论】:

    • 对不起。仅替换第一次出现。
    【解决方案2】:

    您也可以捕获字符串而不是 preg_replace:

    (?:(?:www.|http::?\/\/)?example\.com\/)+(.*)
    

    唯一的捕获组包含您要查找的字符串。见here

    另外,我注意到您的输入字符串中有http::。我在正则表达式中将其与相同的匹配,但使用? 以防万一。最后一件事,{0,1} 可以写成?。它更短:)

    PHP 代码(我不太熟悉该语言,但我相信这应该可行):

    preg_match('/(?:(?:www.|http::?\/\/)?example\.com\/)+(.*)/', $html, $matches);
    $url = $matches[1];
    

    【讨论】:

    • 这个使用preg_match。但是您仍然可以使用preg_replace 并替换为\1
    • @Arif 我对 PHP 不太熟悉,但我相信这应该可行:preg_match('/(?:(?:www.|http::?\/\/)?example\.com\/)+(.*)/', $html, $matches); $url = $matches[1];
    • 谢谢。这对我帮助很大。 http:: 中的双冒号只是输入错误。
    【解决方案3】:

    首先,PHP 正则表达式引擎允许您使用备用正则表达式分隔符。因此,您可以改用 ~# 并避免转义正斜杠。点也需要转义,因为它是一个特殊的正则表达式字符。

    重构后的正则表达式可以是这样的:

    '~(?:https?://)?(?:www\.)?example\.com/~i'
    

    完整的PHP代码:

    $regex_replace = '~(?:https?://)?(?:www\.)?example\.com/(?!$)~i';
    $string = "www.example.com/example.com/http://example.com/www.abc.com/xyz.com/example.com/";
    $after = preg_replace($regex_replace, '', $string);
    var_dump($after);
    

    输出:

    string(32) "www.abc.com/xyz.com/example.com/"
    

    【讨论】:

    • 这里是我的测试代码$regex_replace = '~^(?:https?://)?(?:www\.)?example\.com/*~i'; $string = "www.example.com/example.com/http://example.com/www.abc.com/xyz.com/example.com"; $after = preg_replace($regex_replace, '', $string); echo $after;
    • 如果您在 example.com 的末尾添加“/”,则此解决方案将失败。那么它也会替换最后一个。
    • 在这种情况下使用$regex_replace = '~(?:https?://)?(?:www\.)?example\.com/(?!$)~i';
    • 检查这个字符串 "example.com/www.abc.com/example.com/xyz.com/example.com" 在这种情况下它也会替换中间的。
    • 您是否首先在问题中明确说明了您的要求?你不能像这样不断地改变你的测试数据。抱歉,您没有聘请我为您完成这项工作。我的解决方案适用于您的原始问题,剩下的您应该能够弄清楚。
    【解决方案4】:

    使用preg_replace$limit参数(本例中的第三个参数):

    preg_replace('/(http:\/\/){0,1}(www.){0,1}example.com(\/)*/i', $replacement, $subject, 1);
    

    【讨论】:

    • limit 意味着只匹配 X 次,所以他仍然会有同样的错误
    猜你喜欢
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 2020-01-11
    • 1970-01-01
    • 2011-08-29
    相关资源
    最近更新 更多