在PHP中大写编码的url的编码部分

时间:2018-09-28 14:22:05

标签: php regex

我有这样的字符串网址:

$url = 'htttp://mysite.com/sub1/sub2/%d8%f01'

我想将url(仅%**子字符串)的编码部分大写,例如'%d8%f01',因此最终的URL为:

htttp://mysite.com/sub1/sub2/%D8%F01

可能使用preg_replace(),但无法创建正确的正则表达式。

有任何线索吗?谢谢!!!

2 个答案:

答案 0 :(得分:2)

您可以使用preg_replace_callback将匹配的%**子字符串转换为大写:

$url = 'http://example.com/sub1/sub2/%d8%f01';
echo preg_replace_callback('/(%..)/', function ($m) { return strtoupper($m[1]); }, $url);

输出:

http://example.com/sub1/sub2/%D8%F01

请注意,如果并非所有的URL都经过编码,这也将起作用,例如:

$url = 'http://example.com/sub1/sub2/%cf%81abcd%ce%b5';
echo preg_replace_callback('/(%..)/', function ($m) { return strtoupper($m[1]); }, $url);

输出:

http://example.com/sub1/sub2/%CF%81abcd%CE%B5

更新

也可以使用直接的preg_replace解决此问题,尽管模式和替换非常重复,因为您必须考虑%之后每个位置的所有可能的十六进制数字:

$url = 'http://example.com/sub1/sub2/%cf%81abcd%ce%5b';
echo preg_replace(array('/%a/', '/%b/', '/%c/', '/%d/', '/%e/', '/%f/', 
                        '/%(.)a/', '/%(.)b/', '/%(.)c/', '/%(.)d/', '/%(.)e/', '/%(.)f/'),
                  array('%A', '%B', '%C', '%D', '%E', '%F', 
                        '%$1A', '%$1B', '%$1C', '%$1D', '%$1E', '%$1F'),
                  $url);

输出:

http://example.com/sub1/sub2/%CF%81abcd%CE%5B

更新2

受@Martin的启发,我进行了一些性能测试,preg_replace_callback解决方案的运行速度通常比preg_replace快25%(0.0156秒与0.02次迭代的0.0220秒)。

答案 1 :(得分:0)

我对PHP一点都不了解,但是这是一个不用Regex的例子(尽管可能是重构的)。无需将Regex与此类内容一起使用。

$str = "http://example.com/sub1/sub2/%d8%f01";

$expl = explode('%', $str);

foreach ($expl as &$val) {
  if(strpos($val, 'http') === false) {
    $val = '%' . strtoupper($val);
  };
}

print_r(join('', $expl));