регулярное выражение Python найти первое слово после определенных ключевых слов - PullRequest
0 голосов
/ 21 марта 2019

У меня есть следующий код Python, который получает первое слово после определенных ключевых слов:

file_tokens = ('DATABASE', 'EXTERNAL_FILE', 'FILE', 'FILENAME', 'INCLUDE')
# match newline, only spaces, then exact token, then spaces, then everything but whitespace
search_pattern = r'\n\s*({})\s+([^\s]*)'.format('|'.join(file_tokens))
matches = re.findall(search_pattern, file_content_string, flags=re.IGNORECASE)  # find matches

Он прекрасно работает в строке вроде следующей (включая новые строки и возврат каретки):

# originaly spe1 but with grd ecl file meddled with for nesting 
include tests

SIMULATION
  SIMULATION_TYPE SUBSURFACE
  PROCESS_MODELS
    SUBSURFACE_FLOW Flow
      MODE BLACK_OIL
      OPTIONS
       ANALYTICAL_JACOBIAN
       ISOTHERMAL
      /
    / ! end of subsurface_flow
  / ! end of process models
  CHECKPOINT
  /
END  !! end simulation block

SUBSURFACE

external_file example1.dat

include example2.dat

со спичками, содержащими:

соответствует = [example1.dat, example2.dat]

но она не работает для простой строки, подобной следующей, содержащей только ключевые слова и другой текст:

external_file example3.dat

include example4.dat

возвращает пустой массив или только последний элемент (немного случайный):

соответствует = [example4.dat] или соответствует = []

есть идеи? Спасибо.

UPDATE

ОК, после изменения текста импорта:

external_file example3.dat

include example4.dat

database example5.dat

Я понял, что в моем массиве совпадений отсутствует только первый элемент:

соответствует = [example4.dat, example5.dat]

Как мне изменить регулярное выражение для включения example3.dat?

Ответы [ 2 ]

0 голосов
/ 21 марта 2019

Вам необходимо заменить \n на ^ и добавить re.M к флажкам:

r'(?mi)^\s*(?:{})\s+(\S+)'.format('|'.join(file_tokens))

Теперь ^\s* будет соответствовать началу строки, а затем 0 или более пробелов.

См. Демонстрационную версию Python :

import re

file_content_string="""external_file example3.dat

include example4.dat

database example5.dat"""

file_tokens = ('DATABASE', 'EXTERNAL_FILE', 'FILE', 'FILENAME', 'INCLUDE')
search_pattern = r'^\s*(?:{})\s+(\S+)'.format('|'.join(file_tokens))
matches = re.findall(search_pattern, file_content_string, flags=re.I|re.M) 
print(matches)

Выход: ['example3.dat', 'example4.dat', 'example5.dat']

0 голосов
/ 21 марта 2019

Я бы решил немного иначе.

import re
test1 = """include tests

SIMULATION
  SIMULATION_TYPE SUBSURFACE
  PROCESS_MODELS
    SUBSURFACE_FLOW Flow
      MODE BLACK_OIL
      OPTIONS
       ANALYTICAL_JACOBIAN
       ISOTHERMAL
      /
    / ! end of subsurface_flow
  / ! end of process models
  CHECKPOINT
  /A
END  !! end simulation block

SUBSURFACE

external_file example1.dat

include example2.dat"""

test2 = """external_file example3.dat

include example4.dat"""

token = re.findall(r'\S+', test1)
token
>>>['include',
 'tests',
 'SIMULATION',
 'SIMULATION_TYPE',
 'SUBSURFACE',
 'PROCESS_MODELS',
 'SUBSURFACE_FLOW',
 'Flow',
 'MODE',
 'BLACK_OIL',
 'OPTIONS',
 'ANALYTICAL_JACOBIAN',
 'ISOTHERMAL',
 '/',
 '/',
 '!',
 'end',
 'of',
 'subsurface_flow',
 '/',
 '!',
 'end',
 'of',
 'process',
 'models',
 'CHECKPOINT',
 '/',
 'END',
 '!!',
 'end',
 'simulation',
 'block',
 'SUBSURFACE',
 'external_file',
 'example1.dat',
 'include',
 'example2.dat']

Когда вы пометите свои слова токсинами, я соберу би-граммы

bi_grams = [(a,b) for a,b in zip(token[:-1], token[1:]) ]

и затем отфильтруйте те биграммы, которые содержат ваши файловые токены, в качестве первой записи

file_tokens = ('DATABASE', 'EXTERNAL_FILE', 'FILE', 'FILENAME', 'INCLUDE')
bi_grams_of_interest = [bi_gram for bi_gram in bi_grams if bi_gram[0].upper() in file_tokens]
bi_grams_of_interest
>>>[('include', 'tests'),
 ('external_file', 'example1.dat'),
 ('include', 'example2.dat')]

если вы запустите это для test2, я получу следующий вывод

>>>[('external_file', 'example3.dat'), ('include', 'example4.dat')]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...