Вы можете просто построить выражение из списка шаблонов с разделителем |
. Вам нужно только убедиться, что более длинные шаблоны предшествуют более коротким, потому что оператор |
не жадный:
patterns = """JJ JJ JJ JJ
JJ JJ JJ NNS
JJ JJ NN NN
JJ JJ NN
JJ JJ NNS
JJ JJ RB
JJ JJ
JJ NN IN DT JJ
JJ NN JJ NNS
JJ NN JJ
JJ NN NN NN
JJ NN NN
JJ NN NNS
JJ NN
JJ NNP
JJ NNS IN NN
JJ NNS IN NN
JJ NNS NN
JJ NNS NNS
JJ NNS
JJ VBG NNS
JJ VBZ NNS
JJR NN"""
import re
pattern = "|".join(sorted(patterns.split("\n"),key=len,reverse=True))
results = re.findall(pattern,patterns) # finds them all in 0.009 ms
Это в 3 раза быстрее, чем сложное выражение:
pattern = '^((JJ(?:R)*\s*)+\s*((((NN(?:S|P)*|VB(:?G|Z)*|RB|JJ)\s*))+\s*)+(((IN|NN(?:S|P)*|DT|JJ)\s*))*)$'
results = re.findall(pattern,patterns)
# takes forever (possibly because of new lines in the text).
# taking end of lines out of the equation:
singleLine = patterns.replace("\n","*")
result = re.findall(pattern, singleLine)
# takes 0.030 ms