Поиск стандартизированного текстового шаблона в строке - PullRequest
0 голосов
/ 18 марта 2020

Мы просматриваем очень большой набор строк для шаблонов стандартных чисел, чтобы найти номера листов чертежа. Например, допустимые номера листов: A-101, A101, C -101, C102, E-101, A1, C1, A-100-A и т. Д.

Они могут содержаться в строке, такой как «Номер листа - это план первого этажа A-101»

Шаблоны номеров листов всегда состоят из одинаковых шаблонов типа символов (цифры, символы и разделители (-, пробел, _)), и если мы преобразуем все действительные числа в шаблон, указывающий тип символа (A-101 = ASNNN, A101 = ANNN, A1 - AN и т. д. c), то всего ~ 100 действительные шаблоны.

Наш план состоит в том, чтобы преобразовать каждый символ в строке в его тип символа и затем найти допустимый шаблон. Таким образом, вопрос в том, что является лучшим способом поиска в «AAASAAAAASAAAAAASAASASNNNSAAAAASAAAAASAAAA», чтобы найти один из 100 допустимых шаблонов типов символов. Мы рассмотрели возможность выполнения 100 текстовых поисков для каждого шаблона, но, похоже, мог бы быть лучший способ найти шаблон-кандидат, а затем выполнить поиск, чтобы определить, является ли он одним из 100 допустимых шаблонов.

Ответы [ 3 ]

2 голосов
/ 18 марта 2020

Решение

Это то, что вы хотите?

import re

pattern_dict = {
    'S': r'[ _-]',
    'A': r'[A-Z]',
    'N': r'[0-9]',
}

patterns = [
    'ASNNN',
    'ANNN',
    'AN',
]

text = "A-1 A2 B-345 C678 D900 E80"

for pattern in patterns:
    converted = ''.join(pattern_dict[c] for c in pattern)
    print(pattern, re.findall(rf'\b{converted}\b', text))

вывод:

ASNNN ['B-345']
ANNN ['C678', 'D900']
AN ['A2']

Объяснение

  • rf'some\b {string}': комбинация r-строки и f-строки.
  • r'some\b': необработанная строка. Это предотвращает экранирование python строки. То же самое с 'some\\b'
  • f'{string}': строка в буквальном формате. Python 3.6+ поддерживает этот синтаксис. Это похоже на '{}'.format(string).
  • Так что вы можете изменить rf'\b{converted}\b' на '\\b' + converted + '\\b'.
  • \b в регулярном выражении: соответствует границе слова.
1 голос
/ 18 марта 2020
    bookmark_strings = []
    bookmark_strings.append("I-111 - INTERIOR FINISH PLAN & FINISH SCHEDULE")
    bookmark_strings.append("M0.01   SCHEDULES & CALCULATIONS")
    bookmark_strings.append("M-1 HVAC PLAN - OH Maple Heights PERMIT")
    bookmark_strings.append("P-2 - PLUMBING DEMOLITION")

    pattern_dict = {
        'S': r'[. _-]',
        'A': r'[A-Z]',
        'N': r'[0-9]',
    }
    patterns = [
        'ASNNN',
        'ANSNN',
        'ASN',
        'ANNN'
    ]
    for bookmark in bookmark_strings:
        for pattern in patterns:
            converted = ''.join(pattern_dict[c] for c in pattern)
            if len(re.findall(rf'\b{converted}\b', bookmark)) > 0:
                print ("We found a match for pattern - {}, value = {} in bookmark {}".format(pattern, re.findall(rf'\b{converted}\b', bookmark) , bookmark))  

Выход:

We found a match for pattern - ASNNN, value = ['I-111'] in bookmark I-111 - INTERIOR FINISH PLAN & FINISH SCHEDULE
We found a match for pattern - ANSNN, value = ['M0.01'] in bookmark M0.01   SCHEDULES & CALCULATIONS
We found a match for pattern - ASN, value = ['M-1'] in bookmark M-1 HVAC PLAN - OH Maple Heights PERMIT
We found a match for pattern - ASN, value = ['P-2'] in bookmark P-2 - PLUMBING DEMOLITION
0 голосов
/ 18 марта 2020

используйте регулярное выражение

import re

re.findall("[A-Z][-_ ]?[0-9]+",text)
...