Регулярное выражение для имени объекта Amazon S3 - PullRequest
0 голосов
/ 05 ноября 2019

Из документа 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\\.]*(\\*)?)?))"

Помимодополнительные символы, которые необходимо добавить в квадратные скобки, выглядит ли это регулярное выражение хорошо или нуждается в дополнительных улучшениях или упрощениях?

1 Ответ

2 голосов
/ 05 ноября 2019

Во-первых, вы regex не совсем работает. Например, для случая /abc/obj.txt он не соответствует части .txt. Смотрите Демонстрацию вашего регулярного выражения . Во-вторых, в подвыражении [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Демонстрация

Analysis of the regex

Но когда я читаю спецификацию для ключей объекта на https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html,, кажется, что ваши тесты не являются допустимыми примерами, поскольку ни один изпоказанные здесь примеры имеют начальные символы /. Также может показаться, что символ * должен рассматриваться как любой другой символ и может появляться много раз в любой позиции. Это делает регулярное выражение намного проще:

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

enter image description here

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...