按规则替换文本中的链接
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.
正则表达式: ((?: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);
我有一个文本,我想将所有 "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.
正则表达式: ((?: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);