PHP/Regex。如何在域之后替换url中的所有百分比(%)字符?

PHP/Regex。如何在域之后替换url中的所有百分比(%)字符?,php,regex,Php,Regex,我有一个问题,我试图为preg_replace创建一个正则表达式,用域名后url中的“u”字符(在域路径中)替换所有百分比(%)字符 例如: 这是c%content和1个url%ehttp://example.com/this%is%image.jpg 这里有一个urlhttp://anotherexample.com/t%his%is%image2.jpg 结果: 这是c%content和1个url%ehttp://example.com/this_is_image.jpg 这里有一个url

我有一个问题,我试图为preg_replace创建一个正则表达式,用域名后url中的“u”字符(在域路径中)替换所有百分比(%)字符

例如:

这是c%content和1个url%ehttp://example.com/this%is%image.jpg
这里有一个urlhttp://anotherexample.com/t%his%is%image2.jpg
结果:

这是c%content和1个url%ehttp://example.com/this_is_image.jpg
这里有一个urlhttp://anotherexample.com/t_his_is_image2.jpg
我的问题是:如何使用
preg\u replace

我所拥有的是用于在img标记中选择域的正则表达式:


/]*>/

像这样使用
dirname()
basename()
stru replace()
怎么样:

$haystack = 'This is c%ontent with 1 url her%e http://example.com/this%is%image.jpg';
$result = dirname($haystack) . '/' . str_replace('%','_',basename($haystack));
echo $result;
结果:

这是c%content和1个url%ehttp://example.com/this_is_image.jpg
这将比使用
preg\u replace()
和正则表达式更有效

更新:

正如ins0指出的,上面的答案取决于只包含一个url的字符串,该url位于末尾。不是很灵活。以下是我在上面发布的另一个想法:

$haystack = 'This is c%ontent with 1 url her%e http://example.com/this%is%image.jpg 
and 1 url here http://anotherexample.com/t%his%is%image2.jpg';

$parts = explode(' ',$haystack);
foreach ($parts as &$part) {
    if (strpos($part,'http://') !== false || strpos($part,'https://') !== false) {
        $part = dirname($part) . '/'. str_replace('%','_',basename($part));
    }
}
$haystack = implode(' ',$parts);
echo $haystack;
结果:

这是c%content和1个url%ehttp://example.com/this_is_image.jpg
这里有一个urlhttp://anotherexample.com/t_his_is_image2.jpg

您可以使用简单的正则表达式匹配字符串中的URL:

// $subject is the string    
preg_match_all('/http:\/\/[^\s]+/', $subject, $matches);
然后循环搜索匹配项,将URL中的
%
替换为
.
,并将其替换为原始
$subject

foreach ($matches as $match) {
    $search = $match;
    $replace = str_replace('%', '_', $match);
    $subject = str_replace($search, $replace, $subject);
}

如果您处理正则表达式替换,我建议
preg\u replace\u callback

请记住,在url中替换
%
可能是危险的,因为url可能包含一些有效的
%
字符,如
http://foo.bar/here%20/index.html
其中
%20
是空白

示例

$haystack = 'This is c%ontent with 1 url her%e http://example.com/this%is%image.jpg 
and 1 url here http://anotherexample.com/t%his%is%image2.jpg';

// please use your fav url regex here
$urlRegex = '#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#';

$haystack = preg_replace_callback($urlRegex, function($url){
    return str_replace('%', '_', $url[0]);
}, $haystack);
$haystack='这是c%content,带有1个url%ehttp://example.com/this%is%image.jpg 
这里有一个urlhttp://anotherexample.com/t%his%is%image2.jpg';
//请在此处使用您最喜欢的url正则表达式
$urlRegex='#\bhtps?://[^\s()]+(?:\([\w\d]+\)|([^[:punct:][\s]|/)#;
$haystack=preg\u replace\u回调($urlRegex,函数($url){
返回str_replace('%','',$url[0]);
}(港币),;

这不像@ins0的答案那么优雅,但我提出了另一个解决方案,我通常不使用php编写代码,因此这可能不是最理想的。如果可以改进,请发表评论

$str3 = "This is c%ontent with 1 url her%e http://example.com/this%is%image.jpg and 1 url here http://anotherexample.com/t%his%is%image2.jpg ";
$regex = "(http\\S+(\\s|$))";
$unmatched = preg_split($regex, $str3);
preg_match_all($regex, $str3, $matches);
$substituted = (str_replace("%", "_", $matches[0]));
$result = "";
foreach($substituted as $key=>$value) {
    $result .= $unmatched[$key];
    $result .= $substituted[$key];
}  
print $result; # for testing

你能分享一下你的尝试和错误吗?也许你真正想要的是?regex不需要一个简单的遗嘱do@wogsland,不,我知道此函数,但将其替换为“\u1”对我来说很重要char.由于要确定您是否选择了一个包含多个URL的字符串中的URL并不容易,我会采取一种简单的方法:将您的句子放入数组中,逐个检查每个单词。如果它是URL,则使用筛选%.然后返回。如果这适用于包含多个URL的字符串,我会感到惊讶(参见OP的示例)。结果是“this_is_image.jpg”-但其中是“this is c%content with 1 url her%e”,它在执行后从内容中删除;)?@ins0-
basename()
dirname()是专门用来提取这样的片段的。我不知道为什么你会认为这是一个肮脏的黑客——我实际上认为它是一个非常干净的一行程序,它能完成任务并使用非常适合任务的函数。@万科-如果你特别需要一个处理一个字符串中的多个URL的方法,那就好了。你不必接受我的答案,但既然这是有用的,而且从技术上回答了你的问题,你至少能给我一次投票吗?:-)@billynoah代码只有在url位于每行末尾时才起作用,因为这一事实代码起作用并且
basename
dirname
作为“预料之中"-否则,此解决方案将替换错误的字符,因为它们不是为处理混合url字符串而设计的。我称之为肮脏的黑客行为,仅仅为了完成这项工作对其他人来说既不是一个好答案,也不是有价值的。关于替换url中的
%
,当你也用其他特殊字符替换所有空格时,这并不危险。还有n替换只是为将来使用它准备内容的一次性过程:)但我会记住它