2017-01-29 7 views
0

У меня есть список строк с именем txtFreeForm:Совпадение уникальные узоры в строке - Python

['Add roth Sweep non vested money after 5 years of termination', 
'Add roth in-plan to the 401k plan.] 

Мне нужно проверить, если только «Добавить Roth» существует в предложении. Для этого я использовал этот

for each_line in txtFreeForm: 
    match = re.search('add roth',each_line.lower()) 
    if match is not None: 
     print(each_line) 

Но это, очевидно, возвращает обе строки в моем списке, как оба содержат "добавить Roth. Есть ли способ исключительно искать «Добавить roth» в предложении, потому что у меня есть куча этих шаблонов для поиска в строках.

Благодарим за помощь!

+3

Почему две строки не должны возвращаться, если они оба содержат «Добавить роуд»? –

+1

'if 'add roth' в each_line.lower(): ...' это гораздо более дешевый способ решения этой проблемы. Не требуется 're'. – DyZ

+0

Я согласен, что «in» - это более дешевый способ сделать это. @AndreiSavin, я знаю, что он вернет оба, если их найти в тексте. но я ищу способ разграничения предложений, которые содержат только «add roth» и те, которые содержат «add roth in plan» –

ответ

0

Вы можете исправить эту проблему, используя свойство .Length строк? Я не опытный программист Python, но вот как я думаю, что это должно работать:

for each_line in txtFreeForm: 
    match = re.search('add roth',each_line.lower()) 
    if (match is not None) and (len(txtFreeForm) == len("Add Roth")): 
     print(each_line) 

В принципе, если текст в строке, а длина строки точно по длине строки «Добавить Roth», тогда он должен ТОЛЬКО содержать «Добавить Roth».

Я надеюсь, что это было полезно.

EDIT:

Я понял, что вы просили. Вы хотите распечатать предложения, содержащие «Добавить Roth», но не предложения, содержащие «Добавить Roth в плане». Это верно?

Как насчет этого кода?

for each_line in txtFreeForm: 
    match_AR = re.search('add roth',each_line.lower()) 
    match_ARIP = re.search('add roth in plan',each_line.lower()) 
    if (match_AR is True) and (match_ARIP is None): 
     print(each_line) 

Похоже, что это должно устранить проблему. Вы можете исключить любые строки (например, «в плане»), ища их и добавив их в сравнение.

+0

. Тогда почему бы не сказать 'each_line.lower() == 'add roth'' напрямую? –

+0

@Michael Kemp ваш код снова вернет обе строки из списка –

+0

@AndreiSavin, что вы предлагаете, является точным соответствием. не добавляйте roth, являющуюся частью предложения. –

0

Вы близко :) Передай это выстрел:

for each_line in txtFreeForm: 
    match = re.search('add roth (?!in[-]plan)',each_line.lower()) 
    if match is not None: 
     print(each_line[match.end():]) 

EDIT: Ааа я неправильно понял ... У вас есть много из них. Это требует более агрессивной магии.

import re 
from functools import partial 

txtFreeForm = ['Add roth Sweep non vested money after 5 years of termination', 
       'Add roth in-plan to the 401k plan.'] 


def roths(rows): 
    for row in rows: 
     match = re.search('add roth\s*', row.lower()) 
     if match: 
      yield row, row[match.end():] 

def filter_pattern(pattern): 
    return partial(lazy_filter_out, pattern) 


def lazy_filter(pattern): 
    return partial(lazy_filter, pattern) 


def lazy_filter_out(pattern, rows): 
    for row, rest in rows: 
     if not re.match(pattern, rest): 
      yield row, rest 

def magical_transducer(bad_words, nice_rows): 
    magical_sentences = reduce(lambda x, y: y(x), [roths] + map(filter_pattern, bad_words), nice_rows) 
    for row, _ in magical_sentences: 
     yield row 

def main(): 
    magic = magical_transducer(['in[-]plan'], txtFreeForm) 
    print(list(magic)) 

if __name__ == '__main__': 
    main() 

Чтобы немного рассказать о происходящем, вы упомянули, что у вас есть много этих слов для обработки. Традиционный способ сравнения двух групп элементов - с вложенными петлями. Так,

results = [] 
for word in words: 
    for pattern in patterns: 
     data = do_something(word_pattern) 
     results.append(data) 
for item in data: 
    for thing in item: 
     and so on... 
     and so fourth... 

Я использую несколько различных методов, чтобы попытаться добиться реализации «льстить» и избегать вложенных циклов. Я сделаю все возможное, чтобы описать их.

**Function compositions** 
# You will often see patterns that look like this: 
x = foo(a) 
y = bar(b) 
z = baz(y) 

# You may also see patterns that look like this: 
z = baz(bar(foo(a))) 

# an alternative way to do this is to use a functional composition 
# the technique works like this: 
z = reduce(lambda x, y: y(x), [foo, bar, baz], a) 
+0

wow. Я даже не понимаю функции. позвольте мне сделать некоторое чтение, а затем вернуться к вам. заранее спасибо –

+0

О, ничего себе, извините! Я должен был быть более ясным в своем посте. Я посмотрю, смогу ли я получить дополнительные сведения о том, что это делает. –