Извлечение ключей и значений из текста с помощью регулярных выражений - PullRequest
0 голосов
/ 10 июля 2020

У меня есть большое количество строк, которые мне нужно проанализировать. Эти строки содержат информацию, которая помещается в пары ключ-значение.

Пример вводимого текста:

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventory veritatis et quasi architeo beatae vitae dicta sunt explicabo. Nemo enim: ipsam voluptatem quia voluptas sit aspernatur aut odit aut fu git, sed quia consquuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consctetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim: ad minima veniam, * 31.12.2012, quis nostrum excitationem ullam corporis suscipit labouriosam, nisi ut aliquid ex ea Commodi Conquatur? Quis autem vel eum iure correhenderit qui in ea voluptate velit esse quam nihil molestiae conquatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur

Ключевая информация:

  • ключ начинается либо с начала строки, либо после \.
  • Ключ всегда заканчивается на :
  • За ключом сразу следует значение
  • Это значение продолжается до следующего ключа или до последнего символа в строке
  • Есть несколько пар ключ-значение, которых я не знаю

Ожидаемый результат

{
    "Nemo enim": "ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem",
    
    "Ut enim": "ad minima veniam, *31.12.2012, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur"
}

Регулярное выражение, которое у меня есть, - ([üöä\w\s]*)\: (.*?)\.. Достаточно сказать, что он не обеспечивает ожидаемого результата.

Ответы [ 3 ]

2 голосов
/ 10 июля 2020

Вы можете сопоставить следующее регулярное выражение, которое сохраняет ключи и значения для захвата групп 1 и 2.

r'(?<![^.]) *([^.]+?:) *((?:(?!\. ).)+)'

Запустите свой движок! | Механизм регулярных выражений Python code

Python выполняет следующие операции.

(?<![^.])    : negative lookbehind asserts current location is not
               preceded by a character other than '.'
\ *          : match 0+ spaces
(            : begin capture group 1
  [^.]+?     : match 1+ characters other than '.', lazily
  :          : match ':'
)            : end capture group 1
\ *          : match 0+ spaces
(            : begin capture group 2
  (?:        : begin non-capture group
    (?!\. )  : negative lookahead asserts current position is not
               followed by a period followed by a space
    .        : match any character other than a line terminator
  )+         : end non-capture group and execute 1+ times
)            : end capture group 2

Он использует метод умеренного жадного токена, который соответствует ряду отдельных символов, которые не начинают нежелательную строку. Например, если бы строка была "concatenate", (?:(?:!cat).)+ соответствовала бы первым трем буквам, но не вторым 'c', поэтому совпадение было бы 'con'.

2 голосов
/ 10 июля 2020

Это регулярное выражение ([^:.]+):\s*([^:]+)(?=\.\s+|$) выполняет свою работу.

Демонстрация и объяснение

0 голосов
/ 10 июля 2020

Просто для удовольствия, вот python решение без регулярных выражений:

latin = """[the sample input text]"""
new_lat = latin.replace(":","xxx:").split('xxx')
for l in new_lat:
    if ":" in l:        
        curr_ind = new_lat.index(l)
        cur_brek = l.rfind('. ')
        prev_brek = new_lat[curr_ind-1].rfind('. ')
        stub = new_lat[curr_ind-1][prev_brek+2:]
        new_l = stub+l[:cur_brek]
        print(new_l)

Вывод - это два текстовых блока, начинающихся с ключа.

...