正则表达式清理网址

时间:2013-07-26 15:10:27

标签: php regex

我正在寻找一种从字符串中获取有效网址的方法:

$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部分,但如果可能的话,希望以正则表达式形式提供更优雅的解决方案。感谢。

3 个答案:

答案 0 :(得分:3)

这将完全符合您的要求:

 <?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)是所谓的lookbehind的语法。 X被我们正在测试的字符替换。

以下表达式将匹配双斜杠(/)的每个实例:

\/\/

但是我们需要确保我们正在寻找的匹配前面没有:字符,所以我们需要'lookbehind'我们的匹配以查看:字符是否存在。如果是,那么我们不希望它被算作匹配:

(?<!:)\/\/

!是什么说不匹配我们的lookbehind。如果我们将其更改为(?=:)\/\/,那么它只会匹配在它们之前具有:的双斜杠。

这是一个快速教程,可以比lookahead and lookbehind tutorial

更好地解释它

答案 1 :(得分:2)

假设你所有的字符串都是给定的形式,你不需要任何但最简单的正则表达式来做到这一点;如果你想要一个优雅的解决方案,那么正则表达式肯定不是你需要的。此外,双斜线在URL中是合法的,就像在Unix路径中一样,并且意味着单个斜杠的作用相同,因此您根本不需要完全删除它们。

为什么不

$url = array_shift(preg_split('/\|/', $string));

如果您真的非常关心删除URL中的双斜线,那么您可以按照

进行操作
$url = preg_replace('/([^:])\/\//', '$1/', $url);

甚至将它们组合成

$url = preg_replace('/([^:])\/\//', '$1/', array_shift(preg_split('/\|/', $string)));

虽然最后一种形式有点毛茸茸。

答案 2 :(得分:0)

由于这是一个非常严格定义的情况,我认为只有一个preg是最优雅的解决方案。

从头到尾:

$sanitizedURL = preg_replace('~((?<!:)/(?=/)|\\|.+)~', '', $rawURL);

基本上,它的作用是查找任何前面的斜杠,它不是以冒号(:)开头,而后面跟着bij另一个正斜杠。它还会搜索任何管道字符及其后面的任何字符。

找到的任何内容都会从结果中删除。

如果您愿意,我可以更详细地解释RegEx。