我有一个包含aws s3 url的变量
s3://bucket_name/folder1/folder2/file1.json
我想在变量中获取bucket_name并在另一个变量中休息,即/folder1/folder2/file1.json。我尝试了正则表达式,可以像下面那样得到bucket_name,不确定是否有更好的方法。
m = re.search('(?<=s3:\/\/)[^\/]+', 's3://bucket_name/folder1/folder2/file1.json')
print(m.group(0))
我如何得到其余的东西,即folder1 / folder2 / file1.json?
我已检查是否有boto3功能从网址中提取bucket_name和密钥,但找不到它。
答案 0 :(得分:42)
由于它只是一个普通网址,因此您可以使用urlparse
获取网址的所有部分。
>>> from urlparse import urlparse
>>> o = urlparse('s3://bucket_name/folder1/folder2/file1.json', allow_fragments=False)
>>> o
ParseResult(scheme='s3', netloc='bucket_name', path='/folder1/folder2/file1.json', params='', query='', fragment='')
>>> o.netloc
'bucket_name'
>>> o.path
'/folder1/folder2/file1.json'
您可能必须从键中删除开始斜杠,如下一个答案所示。
o.path.lstrip('/')
随着Python 3 urlparse
移至urllib.parse
,请使用:
from urllib.parse import urlparse
这是一个负责处理所有细节的课程。
try:
from urlparse import urlparse
except ImportError:
from urllib.parse import urlparse
class S3Url(object):
"""
>>> s = S3Url("s3://bucket/hello/world")
>>> s.bucket
'bucket'
>>> s.key
'hello/world'
>>> s.url
's3://bucket/hello/world'
>>> s = S3Url("s3://bucket/hello/world?qwe1=3#ddd")
>>> s.bucket
'bucket'
>>> s.key
'hello/world?qwe1=3#ddd'
>>> s.url
's3://bucket/hello/world?qwe1=3#ddd'
>>> s = S3Url("s3://bucket/hello/world#foo?bar=2")
>>> s.key
'hello/world#foo?bar=2'
>>> s.url
's3://bucket/hello/world#foo?bar=2'
"""
def __init__(self, url):
self._parsed = urlparse(url, allow_fragments=False)
@property
def bucket(self):
return self._parsed.netloc
@property
def key(self):
if self._parsed.query:
return self._parsed.path.lstrip('/') + '?' + self._parsed.query
else:
return self._parsed.path.lstrip('/')
@property
def url(self):
return self._parsed.geturl()
答案 1 :(得分:13)
对于那些喜欢我的人试图使用urlparse来提取密钥和存储桶以便用boto3创建对象。有一个重要的细节:从键的开头删除斜杠
from urlparse import urlparse
o = urlparse('s3://bucket_name/folder1/folder2/file1.json')
bucket = o.netloc
key = o.path
boto3.client('s3')
client.put_object(Body='test', Bucket=bucket, Key=key.lstrip('/'))
需要一段时间才能意识到因为boto3没有抛出任何异常。
答案 2 :(得分:7)
无需urllib或re(也处理前面的斜杠)的解决方案:
def split_s3_path(s3_path):
path_parts=s3_path.replace("s3://","").split("/")
bucket=path_parts.pop(0)
key="/".join(path_parts)
return bucket, key
运行:
bucket, key = split_s3_path("s3://my-bucket/some_folder/another_folder/my_file.txt")
返回:
bucket: my-bucket
key: some_folder/another_folder/my_file.txt
答案 3 :(得分:3)
如果您想使用正则表达式,可以执行以下操作:
>>> import re
>>> uri = 's3://my-bucket/my-folder/my-object.png'
>>> match = re.match(r's3:\/\/(.+?)\/(.+)', uri)
>>> match.group(1)
'my-bucket'
>>> match.group(2)
'my-folder/my-object.png'
这样做的好处是,您可以检查s3
方案,而不是在那里允许任何内容。
答案 4 :(得分:3)
这是一个不错的项目:
s3path是aws s3服务的pathlib扩展
>>> from s3path import S3Path
>>> path = S3Path.from_uri('s3://bucket_name/folder1/folder2/file1.json')
>>> print(path.bucket)
'/bucket_name'
>>> print(path.key)
'folder1/folder2/file1.json'
>>> print(list(path.key.parents))
[S3Path('folder1/folder2'), S3Path('folder1'), S3Path('.')]
答案 5 :(得分:2)
只需一行内置字符串方法就可以轻松完成...
s3_filepath = "s3://bucket-name/and/some/key.txt"
bucket, key = s3_filepath.replace("s3://", "").split("/", 1)
答案 6 :(得分:1)
我做的最简单的是:
s = 's3://bucket/path1/path2/file.txt'
s1 = s.split('/', 3)
bucket = s1[2]
object_key = s1[3]
答案 7 :(得分:0)
这里是使用正则表达式的单行代码:
import re
s3_path = "s3://bucket/path/to/key"
bucket, key = re.match(r"s3:\/\/(.+?)\/(.+)", s3_path).groups()
答案 8 :(得分:0)
我使用以下正则表达式:
^(?:[s|S]3:\/\/)?([a-zA-Z0-9\._-]+)(?:\/)(.+)$
如果匹配,则 S3 解析部分如下:
此模式处理带或不带 s3://
uri 前缀的存储桶路径。
如果要允许其他合法存储桶名称字符,请根据需要修改模式的 [a-zA-Z0-9_-]
部分以包含其他字符。
完整的 JS 示例(以 Typescript 形式)
const S3_URI_PATTERN = '^(?:[s|S]3:\\/\\/)?([a-zA-Z0-9\\._-]+)(?:\\/)(.+)$';
export interface S3UriParseResult {
bucket: string;
name: string;
}
export class S3Helper {
/**
*
* @param uri
*/
static parseUri(uri: string): S3UriParseResult {
const re = new RegExp(S3_URI_PATTERN);
const match = re.exec(uri);
if (!match || (match && match.length !== 3)) {
throw new Error('Invalid S3 object URI');
}
return {
bucket: match[1],
name: match[2],
};
}
}
答案 9 :(得分:0)
最近的一个选项是使用 cloudpathlib
,它为云服务(包括 S3、Google Cloud Storage 和 Azure Blob Storage)上的文件实现 pathlib
函数。
除了这些功能之外,您还可以轻松获取 S3 路径的存储桶和密钥。
from cloudpathlib import S3Path
path = S3Path("s3://bucket_name/folder1/folder2/file1.json")
path.bucket
#> 'bucket_name'
path.key
#> 'folder1/folder2/file1.json'