我有这样的字符串网址:
$url = 'htttp://mysite.com/sub1/sub2/%d8%f01'
我想将 url 的编码部分(仅%**
子字符串(大写,因为示例是'%d8%f01'
因此最终 url 将是:
htttp://mysite.com/sub1/sub2/%D8%F01
可能使用preg_replace()
,但无法制作正确的正则表达式。
有什么线索吗?谢谢!!!
您可以使用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 秒对 10000 次迭代的 0.0220 秒(。
我对PHP 一点也不了解,但这里有一个例子(尽管是一个可以重构的合在一起的例子(如何在没有正则表达式的情况下做到这一点。没有必要将正则表达式与这样的东西一起使用。
$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));