У меня есть файл, который я пытаюсь разобрать, который включает пары ключ-значение. Где ключ начинается с «-», за которым следуют альфа-символы и значение, предшествующее ему, как показано на рисунке ниже.
Когда я анализирую файл с приведенным ниже шаблоном регулярного выражения, я легко могу получить ключи и значения, но когда значения включают несколько слов или данных в кавычках (которые также соответствуют значению ключа), сопоставление моего шаблона не выполняется. Я пробовал несколько итераций сопоставления шаблонов регулярных выражений, но не смог получить желаемый результат. Мне удалось найти шаблон регулярного выражения, соответствующий цитируемому тексту '"(.*?)"', но я не смог использовать оба шаблона одновременно. Любая помощь в получении желаемого результата очень ценится.
Мой код (желаемые результаты только для первой строки):
mystring = '''-desc none -type used -cost med -color blue
-desc none -msg This is a a message -name test
-desc "(-type old -cost high)" -color green'''
mydict = {}
item_num = 0
for line in mystring.splitlines():
quoted = re.findall('"(.*?)"', line)
key_value = re.findall('(-\w+\s+)(\S+)', line)
print(key_value)
### Output ###
[('-desc ', 'none'), ('-type ', 'used'), ('-cost ', 'med'), ('-color ', 'blue')]
[('-desc ', 'none'), ('-msg ', 'This'), ('-name ', 'test')]
[('-desc ', '"(-type'), ('-cost ', 'high)"'), ('-color ', 'green')]
### Desired Output ###
[('-desc ', 'none'), ('-type ', 'used'), ('-cost ', 'med'), ('-color ', 'blue')]
[('-desc ', 'none'), ('-msg ', 'This is a message'), ('-name ', 'test')]
[('-desc ', "(-type old -cost high)"), ('-color ', 'green')]
Это удивительное волшебство RegEx! Да сработало именно так, как хотелось. Не могли бы вы дать краткое объяснение используемого здесь шаблона регулярного выражения? Спасибо.





Вы можете использовать
(-\w+)\s+("[^"]*"|.*?)(?=$|\s*-\w+\s)
См. демонстрация регулярных выражений.
Подробности
(-\w+) - Группа 1: - и более 1 символа слова\s+ - 1+ пробелы("[^"]*"|.*?) - Группа 2: ", 0+ символов, кроме ", а затем " или любые 0+ символов, кроме символов разрыва строки, как можно меньше, до первого...(?=$|\s*-\w+\s) - конец строки или 0+ пробелов, -, 1+ словесных символов и пробел.Регулярный график:
См. демонстрация Python:
import re
mystring = '''-desc none -type used -cost med -color blue
-desc none -msg This is a a message -name test
-desc "(-type old -cost high)" -color green'''
mydict = {}
for line in mystring.splitlines():
key_value = re.findall(r'(-\w+)\s+("[^"]*"|.*?)(?=$|\s*-\w+\s)', line)
print(key_value)
Выход:
[('-desc', 'none'), ('-type', 'used'), ('-cost', 'med'), ('-color', 'blue')]
[('-desc', 'none'), ('-msg', 'This is a a message'), ('-name', 'test')]
[('-desc', '"(-type old -cost high)"'), ('-color', 'green')]
Это круто. Спасибо за подробное объяснение и наглядность!
Это лучшее регулярное выражение, которое вы могли бы использовать:
Никогда не поздно изменить свой голос.
регулярное выражение сырое:
(?<!\S)-(\w+)\s+("[^"]*"|[^\s"-]+(?:\s+[^\s"-]+)*)(?!\S)
необработанный питон:
r"(?<!\S)-(\w+)\s+(\"[^\"]*\"|[^\s\"-]+(?:\s+[^\s\"-]+)*)(?!\S)"
https://regex101.com/r/7bYN1A/1
Ключ = группа 1
Значение = группа 2
(?<! \S )
-
( \w+ ) # (1)
\s+
( # (2 start)
" [^"]* "
| [^\s"-]+
(?: \s+ [^\s"-]+ )*
) # (2 end)
(?! \S )
Ориентир
Regex1: (?<!\S)-(\w+)\s+("[^"]*"|[^\s"-]+(?:\s+[^\s"-]+)*)(?!\S)
Options: < none >
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 10
Elapsed Time: 1.66 s, 1660.05 ms, 1660048 µs
Matches per sec: 301,196
Сюда не входят значения со специальными символами, такими как "\" и "\&". Например: "-desc n&one -type used -cost med -color bl\ue". Вот это не соответствие "n&one" и "blue". Можно ли обновить его, чтобы включить специальные символы в значения?
@MBasith - Считаются ли кавычки одним значением: -this "quoted"? или его можно смешивать в значении с другими символами/кавычками: -that here"quoted"there"quoted" ? Или значение может содержать 1,2,3,4, .... разные кавычки? Если вы не знаете, это нормально.
Котировки считаются одним значением. Значение будет содержать только одну пару кавычек.
Это прекрасно работает! Могу я спросить, как вы это создали? Было ли это просто благодаря общим знаниям и опыту использования RegEx или у вас есть какой-то инструмент, который может помочь?
Я использую RegexFormat для разработки, тестирования, обслуживания и эталонного регулярного выражения. У меня есть сотни файлов регулярных выражений, которые я разработал. Используя этот инструмент, вы значительно сократите время обучения.
Проверьте ideone.com/YSw8Cr — работает ли он должным образом?