从S3 URL中提取存储桶和资源名称(正则表达式问题)

3

我将收到以下任意一项输入。我需要设计一个正则表达式,可以处理其中任何一项,并提取有效的S3存储桶名称和有效的S3资源名称。

http://s3.amazonaws.com/validS3bucketname/validS3resourcename
https://s3.amazonaws.com/validS3bucketname/validS3resourcename
http://validS3bucketname.s3.amazonaws.com/validS3resourcename
https://validS3bucketname.s3.amazonaws.com/validS3resourcename

validS3bucketname和validS3resourcename是有效的S3值,包括空格和其他任何字符 - 我不知道S3允许哪些文件名作为有效文件名。


你想仅提取$bucket和$resource吗?或者是resource和bucket可以是任何以$开头的变量名吗? - AabinGunz
抱歉,它可以是任何东西 - $符号只是我的标记...我会更正的。@Abhishek Simon - siliconpi
2个回答

4
也许这些可以结合起来。把它当作灵感:
第一种情况:
^https?://s3\.amazonaws\.com\/([^/]+)/(.+)$

第二种情况:
^https?://([^/]+)\.s3\.amazonaws\.com\/(.+)$

@jensgram - 我不知道它将是哪种输入类型。 - siliconpi
@matt74tm 那就先尝试第一个情况。如果没有匹配,再尝试第二个 :) - jensgram
这个可以运行,但是 ([^/]+) 部分有些问题:/^https?://s3.amazonaws.com/(.+)/(.+)$/ - siliconpi
@matt74tm 如果您使用 / 作为分隔符,那么在正则表达式中必须对其进行转义:/^https?://([^\/]+)\.s3\.amazonaws\.com\/(.+)$/(或更改分隔符)。如果您坚持使用另一种方式,请考虑使用懒惰匹配:/^https?:\/\/s3\.amazonaws\.com\/(.+?)\/(.+?)$/ - jensgram
@jensgram - 我该如何在 preg_match 中保守/“懒惰”地匹配资源名称? - siliconpi
@matt74tm 不理解 :( 但是我发现我在两个地方都使用了懒惰模式(.+ = 贪婪, .+? = 懒惰)。应该只是 /^https?:\/\/s3\.amazonaws\.com\/(.+?)\/(.+)$/。你试过这个吗:/^https?:\/\/([^\/]+)\.s3\.amazonaws\.com\/(.+)$/ - jensgram

2
以下内容都可以匹配:
/:\/\/s3\.amazonaws.com\/([^\/]+)|:\/\/([^.]+)\.s3\.amazonaws\.com\//

这个简单的函数应该很好地封装它

function getS3Info($url) {
    if(! preg_match('/(?:\/\/s3\.amazonaws.com\/([^\/]+)|:\/\/([^.]+)\.s3\.amazonaws\.com)\/([^\/]+)/', $url, $a)) {
        return false;
    }

    $bucket = isset($a[2]) ? $a[2] : $a[1];
    $resource = $a[3];

    return array('bucket' => $bucket, 'resource' => $resource);
}

我喜欢它,而且运行得非常好!但是我不明白为什么在文件夹名称时使用([^\ /]+),而在“域名”时使用([^.]+) - 你能帮我理解一下吗?@詹姆斯 - siliconpi
我该如何正确匹配资源名称? - siliconpi
抱歉,我完全忘记了这个资源。已经编辑了我的答案。 - James C
你需要将isset更改为empty($a[1]),然后它就可以完美地工作了。否则,它无法正常工作http://s3.amazonaws.com/abced/def.mp4 - siliconpi
糟糕 - 对不起,我实际上没有运行代码!现在它能工作太棒了。 - James C

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