Несколько регулярных выражений или условий с использованием групп - PullRequest
0 голосов
/ 16 мая 2019

Я пытаюсь сопоставить несколько различных синтаксисов имен файлов с одним регулярным выражением. Другими словами, я пытаюсь сопоставить строку имени файла с одинаковыми символами в разных порядках. Проблема в том, что я не знаю, как связать воедино "ИЛИ" | случаи, когда речь идет о группах.

Групповой синтаксис:

  • Названия продуктов представляют собой любую букву, любое число с необязательными «-», «_» или пробелами между символами. «-», «_» или пробелы никогда не ставятся в начале или конце названия продукта.
  • PAF или PA всегда имеют начальный "-", за которым следует трейлинг "-", а затем номер.
  • Коды редакций составляют «FG», «RD», «X», «A» или «\ d +», все, кроме последнего, за которым следуют непосредственно, кроме числа.
  • Номер листа в нижнем или верхнем регистре (отсюда re.IGNORECASE), перед которым ставится пробел или ничто, затем слово «лист», затем пробел или ничто и затем число.

Имена файлов следуют за этими образцами:

  • (Название продукта) - (PAF / PA- #) (Лист №) - (Редакция)
  • (\ ш (: \ ш * (: - |? \ S | _) \ ш +) *?) (- PA (: F |) - \ d +?) (?:? (: \ S | -) листа (?: \ S | -) \ d +) (- (?: FG | РД | Х | А |) \ d +)
  • (Название продукта) - (PAF / PA - #) - (Редакция) (Лист №)
  • (\ ш (: \ ш * (: - |? \ S | _) \ ш +) *?) (- PA (: F |) - \ d +?) (?:? (: \ S | -) листа (?: \ S | -) \ d +) (- (?: FG | РД | Х | А |) \ d +)
  • (Название продукта) - (PAF / PA - #) - (Редакция)
  • (\ ш (: \ ш * (: - | \ S | _) \ W +) *??) (- PA (: F |) - \ d +) (- (?: FG | RD | X | |) \ d +)
  • (Название продукта) - (Редакция) (Лист №)
  • (\ ш (: \ ш * (: - | \ S | _) \ W +) *??) (- (?: FG | RD | X | |) \ d +) (:(? : \ s | -) листа (?: \ s | -) \ d +)
  • (Название продукта) - (Редакция)
  • (\ ш (: \ ш * (: - |?? \ S | _) \ ш +) *) (- (?: FG | RD | X | |) \ d +)

PAF PA - обозначения типа продукта, Sheet # - бесполезная информация, а FG #, RD #, X #, A # или # - версии продукта. Мне нужно, чтобы название продукта, обозначение и ревизия были в их собственной группе.

^(\w(?:\w*(?:-|\s|_)?\w+)*)
(?:
(-(?:FG|RD|X|A|)\d+)|
(-PA(?:F|)-\d+)(-(?:FG|RD|X|A|)\d+)|
(-PA(?:F|)-\d+)(?:(?:\s|-)sheet(?:\s|-)\d+)|
(-PA(?:F|)-\d+)(?:(?:\s|-)sheet(?:\s|-)\d+)(-(?:FG|RD|X|A|)\d+)
)
(?:.*)?$

Я пробовал приведенное выше регулярное выражение, но оно не работает правильно. Сначала возвращается слишком много групп, мне бы хотелось только 3.

pattern = re.compile(r'''^(\w(?:\w*(?:-|\s|_)?\w+)*)        # match any alphanumeric and dashes without leading or trailing dashes
                         (-PA(?:F|)-\d+)                    # match '-PAF-<number>' or '-PA-<number>'
                         (?:(?:\s|-|)?sheet(?:\s|-|)?\d+)?  # match '?sheet?<number>' where ? can be <space> or '-'
                         (-(?:FG|RD|X|A|)\d+)?              # match '-FG<number>', '-RD<number>', '-X<number>', '-A<number>' or <number>
                         (?:.*)?$''', flags=re.IGNORECASE|re.VERBOSE)

Вышеупомянутые строки должны совпадать с регулярным выражением.

Ответы [ 2 ]

1 голос
/ 16 мая 2019

РЕДАКТИРОВАТЬ после новых примеров

Чтобы не усложнять шаблон регулярных выражений (что уже достаточно), я бы сначала избавился от части "sheet".

Итак, во-первых, удалите шаблон "sheet #" из имени файла перед применением инструкции соответствия.

Это уменьшит ваши случаи только до следующих шаблонов:

  • (ProductИмя) - (PAF / PA - #) - (Редакция)

  • (Название продукта) - (Редакция)

Затем примените регулярное выражениеразделить на три группы.Для ревизионной группы я использовал (?! ...) отрицательное предпросмотровое утверждение для обработки таких случаев: «2400PSUA-8-PA-1-X0»

Вот пересмотренный код:

import re

string = """10G-HUB-PAF-1 Sheet 1-FG0
HUB-DISP-SPCR-RD0
HUB-MAIN-PA-1-FG0
2400ODU-PA-1-X0 Sheet 1
2400PSUA-8-PA-1-Sheet1-X0
2405OE-PAF-1-FG0
2400PSUA-8-PA-1-Sheet1-X0
XXXX-XXX-123-PAF-1-FG0 Sheet 1
"""

regex = r'(?# product name )(.*?)' + \
        r'(?# PA|PAF       )(?:(?:-)(?:(PAF-\d|PA-\d).*))?' + \
        r'(?# Revision     )(?:-)((?:\d)(?!.*(?:FG|RD|X|A\d))|(?:(?:FG|RD|X|A)\d))'

pattern = re.compile(regex, flags=re.IGNORECASE|re.VERBOSE)

for s in string.splitlines():
    print('String %s' % s)
    # Remove 'Sheet#' or 'Sheet #' or '-Sheet #' or '-Sheet#'
    s=re.sub(r'-?sheet\s?\d','',s, flags=re.IGNORECASE)
    print('Purged string: %s' % s)
    f=pattern.match(s)
    print('group1: %s' % f.group(1))
    print('group2: %s' % f.group(2))
    print('group3: %s\n' % f.group(3))

С некоторым выводом:

String 10G-HUB-PAF-1 Sheet 1-FG0
Purged string: 10G-HUB-PAF-1 -FG0
group1: 10G-HUB
group2: PAF-1
group3: FG0

String HUB-DISP-SPCR-RD0
Purged string: HUB-DISP-SPCR-RD0
group1: HUB-DISP-SPCR
group2: None
group3: RD0

...omitted output ...

String 2400PSUA-8-PA-1-Sheet1-X0
Purged string: 2400PSUA-8-PA-1-X0
group1: 2400PSUA-8
group2: PA-1
group3: X0

String XXXX-XXX-123-PAF-1-FG0 Sheet 1
Purged string: XXXX-XXX-123-PAF-1-FG0 
group1: XXXX-XXX-123
group2: PAF-1
group3: FG0
0 голосов
/ 21 мая 2019

После долгих тренировок с регулярными выражениями и с помощью GDN я нашел решение:

(.*?)(?:(?:\s|_|-|\s?-\s|\s-\s?)(?=(?:PAF-|PA-|FG|RD|X|A)\d+))((?:PAF|PA)-\d+)?(?:\s|_|-|\s?-\s|\s-\s?)?(?:.*?)?((?:FG|RD|X|A)\d+)
import re


def input_loop(pattern, doc_type):
    while True:
        filename = raw_input('Enter {}, Enter "x" to Close: '.format(doc_type))
        if filename == 'x':
            break
        matches = pattern.match(filename)
        if matches:
            groups = matches.groups()
            print groups
        else:
            print '''Couldn't match string: "{}"'''.format(filename)

pattern = re.compile(r'''
  (.*?)(?# Match product name)
  (?:(?:\s|_|-|\s?-\s|\s-\s?)(?=(?:PAF-|PA-|FG|RD|X|A)\d+))(?# Match spacer after product name)
  ((?:PAF|PA)-\d+)?(?# Match optional PAF-# or PA-#)
  (?:\s|_|-|\s?-\s|\s-\s?)?(?# Match spacer after product type name)
  (?:.*?)?(?# Match useless data)
  ((?:FG|RD|X|A)\d+)''', flags=re.IGNORECASE|re.VERBOSE)
input_loop(pattern, 'Assembly Drawings')

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