Regex игнорирует регистр для совпадения, но сохраняет конкретный регистр для результатов - PullRequest
0 голосов
/ 27 марта 2019

Я ищу эффективный способ решения этой проблемы

Допустим, мы хотим найти список слов в строке, игнорируя регистр, но вместо сохранения совпавшей строки нам нужна строка с тем же регистром, что и в исходном списке.

Например:

words_to_match = ['heLLo', 'jumP', 'TEST', 'RESEARCH stuff']
text = 'hello this is jUmp test jump and research stuff'
# Result should be {'TEST', 'heLLo', 'jumP', 'RESEARCH stuff'}

Вот мой текущий подход:

words_to_match = ['heLLo', 'jumP', 'TEST', 'RESEARCH stuff']

Я конвертирую это в следующее регулярное выражение:

regex = re.compile(r'\bheLLo\b|\bjumP\b|\bTEST\b|\bRESEARCH stuff\b', re.IGNORECASE)

Тогда

word_founds = re.findall(regex,'hello this is jUmp test jump and research stuff')
normalization_dict = {w.lower():w for w in words_to_match}
# normalization dict : {'hello': 'heLLo', 'jump': 'jumP', 'test': 'TEST', 'research stuff': 'RESEARCH stuff'}
final_list = [normalization_dict[w.lower()] for w in word_founds]
# final_list : ['heLLo', 'jumP', 'TEST', 'jumP', 'RESEARCH stuff']
final_result = set(final_list)
# final_result : {'TEST', 'heLLo', 'jumP', 'RESEARCH stuff'}

Это мой ожидаемый результат, я просто хочу знать, есть ли более быстрый / более элегантный способ решения этой проблемы.

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

Это можно сделать одной строкой, если вы все еще в порядке с использованием регулярных выражений.

results = set(word for word in re.findall(r"[\w']+", text) if word.lower() in [w.lower() for w in words_to_match])

Здесь используется только разделение переменной text на основе границ слов.

Редактирование:

Вы также можете использовать:

import string
results = set(word for word in "".join(c if c not in string.punctuation else " " for c in text).split() 
              if word.lower() in [w.lower() for w in words_to_match])

, если вы хотите избежать импорта re, но тогда вам нужно использовать string.

Редактировать 2: (после правильного прочтения вопроса, надеюсь)

results = set(word for word in words_to_match if word.lower() in text.lower())

Это также работает с поиском в нескольких словах.

Редактировать 3:

results = set(word for word in words_to_match if re.search(r"\b" + word.lower() + r"\b", text.lower()))
0 голосов
/ 27 марта 2019

Попробуйте это:

words_to_match = ['heLLo', 'jumP', 'TEST'] 
text = 'hello this is jUmp test jump'
result = set()
for str in words_to_match:
    if str.lower() in text.lower():
        result.add(str)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...