Я бы не советовал использовать регулярные выражения для решения этой задачи, потому что язык, который вы хотите разобрать, не является регулярным.
У вас есть символьная строка из нескольких пар ключей. Лучший способ разобрать это - это не совпадение с шаблонами на нем, но для его правильной маркировки.
В стандартной библиотеке Python имеется модуль, называемый shlex
, который имитирует разбор, выполняемый оболочками POSIX, и предоставляет реализацию лексера, которая может быть легко настроена под ваши нужды.
from shlex import shlex
def parse_kv_pairs(text, item_sep=",", value_sep="="):
"""Parse key-value pairs from a shell-like text."""
# initialize a lexer, in POSIX mode (to properly handle escaping)
lexer = shlex(text, posix=True)
# set ',' as whitespace for the lexer
# (the lexer will use this character to separate words)
lexer.whitespace = item_sep
# include '=' as a word character
# (this is done so that the lexer returns a list of key-value pairs)
# (if your option key or value contains any unquoted special character, you will need to add it here)
lexer.wordchars += value_sep
# then we separate option keys and values to build the resulting dictionary
# (maxsplit is required to make sure that '=' in value will not be a problem)
return dict(word.split(value_sep, maxsplit=1) for word in lexer)
Пример запуска:
parse_kv_pairs(
'key1=value1,key2=\'value2,still_value2,not_key1="not_value1"\''
)
Выход:
{'key1': 'value1', 'key2': 'value2,still_value2,not_key1="not_value1"'}
EDIT: Я забыл добавить, что причина, я обычно придерживаться shlex, а не с помощью регулярного выражения (которые в этом случае быстрее) состоит в том, что gi ves вам меньше сюрпризов, особенно если вам нужно позже включить более возможные входы. Я никогда не нашел, как правильно разбирать такие пары ключ-значение с регулярными выражениями, всегда будут входы (например: A="B=\"1,2,3\""
), которые обманут двигатель.
Если вы не заботитесь о таких входах (или, по-другому, если вы можете убедиться, что ваш ввод соответствует определению обычного языка), регулярные выражения отлично.
EDIT2:split
имеет maxsplit
аргумент, что гораздо чище, чем расщепление/нарезка/присоединения. Спасибо @cdlane за его звук!
Можете ли вы отправить ожидаемый выход? –
Будет ли значение 'key2' во втором примере содержать кавычки или нет? т. е. в вашем примере, 'key2' соответствует значению' 'value2, still_value2 "или" "\" value2, still_value2 \ "" '? – EvilTak