1

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

$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 部分,但如果可能的话,我想要一个更优雅的正则表达式解决方案。谢谢。

4

3 回答 3

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 替换为我们正在测试的字符。

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

\/\/

但是我们需要确保我们正在寻找的匹配项前面没有 : 字符,因此我们需要“向后看”我们的匹配项以查看 : 字符是否存在。如果是,那么我们不希望它被视为匹配:

(?<!:)\/\/

这 !就是在我们的回顾中说不匹配。如果我们将其更改为(?=:)\/\/then 它只会匹配前面有 : 的双斜杠。

这是一个快速教程,可以比我 前瞻和后视教程更好地解释这一切

于 2013-07-26T15:20:51.190 回答
2

假设您所有的字符串都采用给定的形式,那么您不需要任何但最简单的正则表达式来执行此操作;如果您想要一个优雅的解决方案,那么绝对不是您需要的正则表达式。此外,双斜杠在 URL 中是合法的,就像在 Unix 路径中一样,并且与单斜杠的作用相同,因此您根本不需要摆脱它们。

为什么不只是

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

?

如果你真的非常关心去掉 URL 中的双斜杠,那么你可以按照这个

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

甚至将它们组合成

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

尽管最后一种形式有点毛茸茸。

于 2013-07-26T15:23:00.240 回答
0

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

从我的头顶:

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

基本上,它的作用是查找前面没有冒号 (:) 的任何正斜杠,并且 IS 后面跟着 bij 另一个正斜杠。它还搜索任何管道字符及其后面的任何字符。

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

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

于 2013-07-27T13:06:42.480 回答