将相对URL转换为绝对URL

3

输入:

  • 基础URL:www.example.com/1/2/index.php
  • 相对URL:../../index.php

输出:

  • 绝对URL:www.example.com/index.php

最好使用sed完成。

我理解的是,这个正则表达式应该删除URL中每个../前面的一个somefolder/


这几乎是一个与https://dev59.com/5G855IYBdhLWcg3wQx_h相同的副本。 - qdinar
4个回答

1
如果你的唯一要求是将..转换为“上一级”,那么这是一个可能的解决方案。它不使用正则表达式、sed,或者 JVM。;)
#!/bin/bash                                                                                                                                

domain="www.example.com"
origin="1/2/3/4/index.php"
rel="../../index.php"

awk -v rel="$rel" -v origin="$origin" -v file="$(basename "$rel")" -v dom="$domain" '                                                                
BEGIN {                                                                                                                                    
    n = split(rel, a, "/")                                                                                                                 
    for(i = 1; i <= n; ++i) {                                                                                                              
        if(a[i] == "..") ++c                                                                                                               
    }                                                                                                                                      
    abs = dom                                                                                                                              
    m=split(origin, b, "/")                                                                                                                
    for(i = 1; i < m - c; ++i) {                                                                                                           
        abs=abs"/"b[i]                                                                                                                     
    }                                                                                                                                      
    print abs"/"file                                                                                                                       
}'

使用awk的另一种方法,感谢Edward提到realpath -m

#!/bin/bash                                                                                                                                

rel="../../index.php"
origin="www.example.com/1/2/index.php"

directory=$(dirname "$origin")
fullpath=$(realpath -m "$directory/$rel")
echo "${fullpath#$(pwd)/}"

1
在Bash中使用sed。
#!/bin/bash

base_url='www.example.com/1/2/index.php'
rel_url='../../index.php'

str="${base_url};${rel_url}"
str=$(echo $str | sed -r 's#/[^/]*;#/#')
while [ ! -z $(echo $str | grep '\.\.') ]
do
  str=$(echo $str | sed -r 's#\w+/\.\./##')
done
abs_url=$str

echo $abs_url

输出:

www.example.com/index.php

1

realpath是一种快速但略微hacky的方法来实现你想要的功能。
(实际上,我很惊讶它没有正确处理URL;它将它们视为普通的旧文件系统路径。)
~$ realpath -m http://www.example.com/1/2/../../index.php => ~$ /home/username/http:/www.example.com/index.php
-m(表示“缺失”)表示即使它的组成部分在文件系统上实际上不存在,也要解析路径。
因此,您仍然必须剥离实际的文件系统部分(这将只是$(pwd))。请注意,协议的双斜杠也被规范化为单个斜杠。因此,最好将输入中的“http://”省略,并将其添加到输出之前。
有关完整说明,请参见man 1 realpath。或者,如果安装了info系统,则可以查看info coreutils 'realpath invocation'以获取更详细的完整说明。


-3

你不能使用单个正则表达式来完成这个任务,因为正则表达式无法计数。

你应该使用真正的编程语言来解决这个问题。即使是Java也可以轻松实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接