按规则替换文本中的链接

Replace links in the text by the rule

我有一个文本,我想将所有 "www.domain.com" 替换为没有“?”符号。

www.domain.com dsa dsad sad sad sa domain.com asdasds adas dsa www.domain.com/someurl/?d sad sadsad www.domain.com/someurl/ asd asd sa www.domain.com?id=123 sd asdsa d

所以我正在搜索带有 preg_match_all() 的文本,并找到所有没有“?”的链接。 运行 循环,当我 运行 str_replace() 它一次替换所有 "domain.com" ,甚至是带有“?”的那个在下一次迭代中,它添加了更多 "add_text" 来替换 domain.com,所以我得到了 "domain.com?add_text?add_text" 的情况,依此类推。我有要从 PREG_OFFSET_CAPTURE 替换的文本的起始位置,但不知道它是否对我有所帮助。 谢谢

$post_content = 'www.domain.com dsa dsad sad sad sa
domain.com asdasds adas dsa
www.domain.com/someurl/?d sad sadsad
www.domain.com/someurl/ asd asd sa
www.domain.com?id=123 sd asdsa d'.'<hr>';

     $pattern = '#(www\.|https?:\/\/)?(domain.com)\S*#i';
                if($num_found = preg_match_all($pattern, $post_content, $out, PREG_OFFSET_CAPTURE))
                {
                  if ($num_found>0){
                    foreach ($out[0] as $k => $v) {
                        if (strpos($v, '?') !== false) {
                            //skip
                        }else{
    //replace
                            $post_content = str_replace($v, $v.'?add_text, $post_content);
                        }
                    }
                  }
                }

输入:

www.domain.com dsa dsad sad sad sa domain.com asdasds adas dsa www.domain.com/someurl/?d sad sadsad www.domain.com/someurl/ asd asd sa www.domain.com?id=123 sd asdsa d

预期输出:

www.domain.com?add_text dsa dsad sad sad sa domain.com?add_text asdasds adas dsa www.domain.com/someurl/?d sad sadsad www.domain.com/someurl/?add_text asd asd sa www.domain.com?id=123 sd asdsa d

所以每个 URL 都有一个 get 参数。每个 URL 没有“?” (get) 必须和 ?add_text 一起,如果已经有 ?something 就跳过它。

您的方法存在根本性缺陷,因为您在替换时没有考虑子字符串。您可能最终会被多次替换并损坏数据。尝试使用 preg_replace() 代替:

<?php
$post_content = 'www.domain.com dsa dsad sad sad sa
domain.com asdasds adas dsa
www.domain.com/someurl/?d sad sadsad
www.domain.com/someurl/ asd asd sa
www.domain.com?id=123 sd asdsa d'.'<hr>';
$pattern = '/((?:https?:\/\/)?(?:www\.)?domain\.com(?!\S*\?))(\S*)/im';
$post_content = preg_replace($pattern, "?add_text", $post_content);
echo $post_content;

正则表达式有点棘手,否定前瞻断言检查没有问号。 The breakdown is here.

PHP code demo

正则表达式: ((?:https?:\/\/)?(?:www\.)?[a-zA-Z]+\.com)(?!\/|\?)|(?:https?:\/\/)?(www\.?[a-zA-Z]+.com\/(?:[^\/]+\/)*)

((?:https?:\/\/)?(?:www\.)?[a-zA-Z]+\.com)(?!\/|\?)

这将匹配例如。 http://www.something.com or https://www.something.com 不再 ?/

((?:https?:\/\/)?www\.?[a-zA-Z]+.com\/(?:[^\/]+\/)*)

这将匹配例如。 http://www.something.com/some/url or https://www.something.com/some/url

<?php
$string='www.domain.com dsa dsad sad sad sa domain.com asdasds adas dsa www.domain.com/someurl/?d sad sadsad www.domain.com/someurl/ asd asd sa www.domain.com?id=123 sd asdsa d';
echo preg_replace("/((?:www\.)?[a-zA-Z]+\.com)(?!\/|\?)|(www\.?[a-zA-Z]+.com\/(?:[^\/]+\/)*)/", "?add_text", $string);