Python: как использовать для цикла в findall - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь использовать цикл for re.findall () в блокноте jupyter. Я хочу извлечь все предложения, содержащие слова «Калифорния», «Колорадо» и «Флорида». Я могу просто написать это.

import re

f =open("C:/Users/uib57309/Desktop/test.txt",mode='rt')
lines = f.read()
f.close()

re.findall(r"([^.]*?California[^.]*\.)",lines)

re.findall(r"([^.]*?Colorado[^.]*\.)",lines)

re.findall(r"([^.]*?Florida[^.]*\.)",lines)

Но как я могу сократить свой код с помощью цикла for? Я пытался так, но это, кажется, неправильно.

test_list = ['California', 'Colorado', 'Florida'] 

for i in test_list: 

     result = re.findall(r"([^.]*?i[^.]*\.)",lines)

print(result)

Ответы [ 4 ]

0 голосов
/ 15 января 2019

вам не нужен цикл, просто создайте регулярное выражение с "|".join

test_list = ['California', 'Colorado', 'Florida']
result = re.findall(r"([^.]*?{}[^.]*\.)".format("|".join(test_list)),lines)

и чтобы убедиться, что слова не являются подстрока, используйте границу слова (на самом деле это не обязательно с этими конкретными словами, но для общего случая это так. Тогда выражение использует еще одну упаковку с r \b символами:

r"([^.]*?{}[^.]*\.)".format("|".join([r"\b{}\b".format(x) for x in test_list]))
0 голосов
/ 15 января 2019

В вашем цикле for результат находит все поиски с буквенным символом строки "i". Используйте стринги (для 3.6+); Конкатенация строк или форматирование тоже подойдут:

result = re.findall(f"([^.]*?{i}[^.]*\.)", lines) # works in Python 3.6+

0 голосов
/ 15 января 2019

Если вы действительно хотите сделать это чисто, вы должны использовать NLTK для разделения предложений. Ваш код основан на предположении, что точка всегда разделяет предложения, но в целом это не так.

import nltk
import re

lines = "Hello, California! Hello, e.g., Florida? Bye Massachusetts"

states = ['California', 'Colorado', 'Florida'] 

# Create a regex from the list of states
states_re = re.compile("|".join(states)) 

results = [sent for sent in nltk.sent_tokenize(lines) \
           if states_re.search(sent)] # Check the condition
#['Hello, California!', 'Hello, e.g., Florida?']
0 голосов
/ 15 января 2019

Используйте границу слова для этой задачи, а также составьте список для хранения.

result переменная будет перезаписываться при каждой итерации цикла.

test_list = ['California', 'Colorado', 'Florida'] 
x = []

for i in test_list: 
    pattern = r"\b"+i+r"\b"
    result = re.findall(pattern,lines)
    x.append(result)

print(x)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...