Использование Regex с lookahead и lookbehind сопоставление с образцом
import re
def parser(x):
# Patterns to search
pattern_on = re.compile(r'(?<= authorized on )(.*?)(\s+)')
pattern_recur = re.compile(r'^(.*?)\s(?=recurring payment)')
m = pattern_on.search(t)
if m:
return m.group(0)
m = pattern_recur.search(t)
if m:
return m.group(0)
return None
tests = ["recurring payment authorized on usps abc", "usps recurring payment abc", "recurring payment authorized on att xxx xxx", "recurring payment authorized on 25.05.1980 xxx xxx", "att recurring payment xxxxx", "12.14.14. att recurring payment xxxxx"]
for t in tests:
found = parser(t)
if found:
print("In text: {}\n Found: {}".format(t, found))
Выход
In text: recurring payment authorized on usps abc
Found: usps
In text: usps recurring payment abc
Found: usps
In text: recurring payment authorized on att xxx xxx
Found: att
In text: recurring payment authorized on 25.05.1980 xxx xxx
Found: 25.05.1980
In text: att recurring payment xxxxx
Found: att
In text: 12.14.14. att recurring payment xxxxx
Found: 12.14.14. att
Пояснение
Совпадение шаблонов Lookahead и Lookbehind
Regex Lookbehind
(? <= Foo) Lookbehind Утверждает, что немедленно текущей позиции в строке предшествует foo </p>
Итак, в шаблоне: r '(? <= авторизация включена) (. *?) (\ s +)' </p>
foo is " authorized on "
(.*?) - matches any character (? causes it not to be greedy)
(\s+) - matches at least one whitespace
Таким образом, вышеприведенное заставляет (. *?) Перехватывать все символы после «авторизации на» до первого символа пробела.
Regex Lookahead
(? = foo) Lookahead утверждает, что сразу за текущей позицией в строке следует foo
То есть: r '^ (. *?) \ s (? = повторяющийся платеж)'
foo is 'recurring payment'
^ - means at beginning of the string
(.*?) - matches any character (non-greedy)
\s - matches white space
Таким образом, (. *?) Будет соответствовать всем символам от начала строки до тех пор, пока мы не получим пробел, за которым следует «повторяющийся платеж»
Лучшая производительность Желательно sinc e Вы применяете к Dataframe, у которого может быть много столбцов.
Выньте компиляцию шаблона из анализатора и поместите его в модуль (сокращение времени на 33%).
def parser(x):
# Use predined patterns (pattern_on, pattern_recur) from globals
m = pattern_on.search(t)
if m:
return m.group(0)
m = pattern_recur.search(t)
if m:
return m.group(0)
return None
# Define patterns to search
pattern_on = re.compile(r'(?<= authorized on )(.*?)(\s+)')
pattern_recur = re.compile(r'^(.*?)\s(?=recurring payment)')
tests = ["recurring payment authorized on usps abc", "usps recurring payment abc", "recurring payment authorized on att xxx xxx", "recurring payment authorized on 25.05.1980 xxx xxx", "att recurring payment xxxxx", "12.14.14. att recurring payment xxxxx"]