【问题标题】:Regular expression for Amazon S3 Object nameAmazon S3 对象名称的正则表达式
【发布时间】:2019-11-06 21:32:18
【问题描述】:

从 aws 文档 https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html 中,我们知道允许作为对象名称一部分的字符。我想构建一个正则表达式,应该像这样指定一个对象或一组对象:

/abc/obj*
/abc/*
/*
/abc/obj1.txt

我创建的正则表达式如下所示:

"((/[a-zA-Z0-9]+)*((/[a-zA-Z0-9\\.]*(\\*)?)?))"

除了需要在方括号内添加的额外符号之外,这个正则表达式看起来不错还是需要更多的增强或简化?

【问题讨论】:

    标签: regex amazon-web-services amazon-s3


    【解决方案1】:

    首先,您的正则表达式不太适用。例如,对于/abc/obj.txt 的情况,它无法匹配.txt 部分。见A demo of your regex。其次,在子表达式[a-zA-Z0-9\\.]中,不需要反斜杠字符; . 将被解释为没有它们的句点字符。第三,您应该在正则表达式的开头添加^,在正则表达式的末尾添加$,以确保您匹配所需的内容,并且输入中没有多余的内容。第四,您没有指定您使用的语言。

    我在这里使用 Python:

    import re
    
    tests = [
        '/abc/obj*',
        '/abc/*',
        '/*',
        '/abc/obj1.txt'
    ]
    
    # the regex: ^/([a-zA-Z0-9]+/)*(\*|([a-zA-Z0-9]+(\*|(\.[a-zA-Z0-9]+)?)))$
    
    for test in tests:
        m = re.match(r"""
            ^                   # the start of the string
            /                   # a leading /
            ([a-zA-Z0-9]+/)*    # 0 or more: abc/
            (\*                 # first choice: *
            |                   # or
            ([a-zA-Z0-9]+       # second choice: abc followed by either:
                (\*|(\.[a-zA-Z0-9]+)?)))    # * or .def or nothing
            $                   # the end of the string
            """, test, flags=re.X)
        print(test, f'match = {m is not None}')
    

    打印:

    /abc/obj* match = True
    /abc/* match = True
    /* match = True
    /abc/obj1.txt match = True
    

    Regex Demo

    但是当我阅读https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html 的对象键规范时,您的测试用例似乎不是有效示例,因为那里显示的示例都没有前导/ 字符。看起来* 字符应该被视为任何其他字符,并且可以在任何位置多次出现。这使得正则表达式实际上更简单:

    ^[a-zA-Z0-9!_.*'()-]+(/[a-zA-Z0-9!_.*'()-]+)*$
    

    Regex Demo

    新代码:

    import re
    
    tests = [
        'abc',
        '-/abc/(def)/!x*yz.def.hij'
    ]
    
    # the regex: ^[a-zA-Z0-9!_.*'()-]+(/[a-zA-Z0-9!_.*'()-]+)*$
    
    for test in tests:
        m = re.match(r"""
            ^                       # the start of the string
            [a-zA-Z0-9!_.*'()-]+    # 1 or more: ~abc*(def)
            (
                /
                [a-zA-Z0-9!_.*'()-]+
            )*                      # 0 or more of /~abc*(def)
            $                       # the end of the string
            """, test, flags=re.X)
        print(test, f'match = {m is not None}')
    

    打印:

    abc match = True
    -/abc/(def)/!x*yz.def.hij match = True
    

    【讨论】:

    • 我尝试了一个似乎可以工作的程序:{ string a = "/abc/lm/hh.txt";正则表达式 b("((/[a-zA-Z0-9]+)*((/[a-zA-Z0-9\\.]*(\*)?)?))"); if ( regex_match(a, b) ) cout
    • @user3552519 转到您的新正则表达式的regex demo,您会发现它不起作用;它与您的任何测试用例的 entire 输入字符串都不匹配。如果输入字符串是"/abc/lm/hh.txt-",你会发现有什么不同吗?这就是为什么我告诉你在你的正则表达式的开头和结尾输入^$ 字符。你有没有试过我的正则表达式?您应该使用 regex01.com 进行测试。
    • 而且[] 内还有反斜杠,这是不必要的。您要求“增强和简化”,但随后忽略了一项重要的增强和简化,即使您不关心我的正则表达式。
    • 你的正则表达式会匹配/abc.txt*,我的不会。我不认为那是你的意图。当您没有针对您要查找的内容的精确 规范但仅提供几个示例时,这就是问题所在。那么它是什么?
    • 感谢您的回答。它实际上工作正常。你能帮我建立一个正则表达式来处理链接docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html中给出的对象的允许字符吗?另外,我想知道您如何构建您在答案中显示的正则表达式图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2011-05-11
    • 2019-08-09
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多