我正在寻找一种从字符串中获得有效url的方法,比如:
$string = 'http://somesite.com/directory//sites/9/my_forms/3-895a3e/somefilename.jpg|:||:||:||:|19845';
我最初的解决方案是:
preg_match('#^[^:|]*#', str_replace('//', '/', $string), $modifiedPath);
但很明显,它将删除http://中的斜线,而不是字符串中间的斜线。
我想要的原始输出是:
http://somesite.com/directory/sites/9/my_forms/3-895a3e/somefilename.jpg
我总是可以先断开字符串的http部分,但如果可能的话,我希望有一个更优雅的regex形式的解决方案。谢谢
这将完全符合您的要求:
<?php
$string = 'http://somesite.com/directory//sites/9/my_forms/3-895a3e/somefilename.jpg|:||:||:||:|19845';
preg_match('/^([^|]+)/', $string, $m); // get everything up to and NOT including the first pipe (|)
$string = $m[1];
$string = preg_replace('/(?<!:)'/'//', '/' ,$string); // replace all occurrences of // as long as they are not preceded by :
echo $string; // outputs: http://somesite.com/directory/sites/9/my_forms/3-895a3e/somefilename.jpg
exit;
?>
编辑:
正则表达式中的(?<!X)
是所谓的查找背后的语法。X将替换为我们正在测试的字符。
以下表达式将匹配双斜杠(/)的每个实例:
'/'/
但我们需要确保我们正在寻找的匹配项之前没有:字符,所以我们需要"查看"我们的匹配项,看看:字符是否在那里。如果是,那么我们不希望它被视为匹配:
(?<!:)'/'/
!就是在我们的背后说不要匹配。如果我们将其更改为(?=:)'/'/
,那么它将只匹配前面有:的双斜杠。
这里有一个快速教程,它可以比我所能解释的更好地向前看和向后看教程
假设所有字符串都是给定的形式,则不需要任何正则表达式,只需要最简单的正则表达式;如果您想要一个优雅的解决方案,那么regex绝对不是您所需要的。此外,双斜杠在URL中是合法的,就像在Unix路径中一样,其含义与单斜杠相同,所以你根本不需要去掉它们。
为什么不只是
$url = array_shift(preg_split('/'|/', $string));
如果你真的非常关心去掉URL中的双斜杠,那么你可以使用
$url = preg_replace('/([^:])'/'//', '$1/', $url);
甚至将它们组合成
$url = preg_replace('/([^:])'/'//', '$1/', array_shift(preg_split('/'|/', $string)));
尽管最后一种形式有点毛茸茸的。
由于这是一个非常严格定义的情况,我认为只有一个preg是最优雅的解决方案。
从我的头顶:
$sanitizedURL = preg_replace('~((?<!:)/(?=/)|''|.+)~', '', $rawURL);
基本上,它所做的是寻找任何前面没有冒号(:)的正斜杠,is后面是bij另一个正斜杠。它还搜索任何管道字符及其后面的任何字符
任何找到的内容都将从结果中删除。
如果你愿意,我可以更详细地解释RegEx。