0

我正在尝试用一个正则表达式匹配几种不同的文件名语法。换句话说,我试图以不同的顺序将文件名字符串与相同的字符匹配。问题是我不知道如何将“OR”串在一起 | 涉及团体的情况。

组语法:

  • 产品名称由任意字母组成,任意数字带有可选的“-”、“_”或字符之间的空格。“-”、“_”或空格绝不会出现在产品名称的开头或结尾。
  • PAF 或 PA 总是有一个前导“-”,后跟一个尾随“-”,然后是一个数字。
  • 修订代码由“FG”、“RD”、“X”、“A”或“\d+”组成,除了最后一个直接跟在后面的数字之外,所有这些都是一个数字。
  • 工作表编号是小写或大写(因此称为 re.IGNORECASE),前面有一个“-”空格或什么都没有,然后是“工作表”这个词,后面是“-”空格或什么都没有,然后是一个数字。

文件名遵循以下模式:

  • (产品名称)-(PAF/PA-#) (Sheet #)-(Revision)
  • (\w(?:\w*(?:-|\s|_)?\w+)*)(-PA(?:F|)-\d+)(?:(?:\s|-)表(?:\s|-)\d+)(-(?:FG|RD|X|A|)\d+)
  • (产品名称)-(PAF/PA-#)-(修订版) (表#)
  • (\w(?:\w*(?:-|\s|_)?\w+)*)(-PA(?:F|)-\d+)(?:(?:\s|-)表(?:\s|-)\d+)(-(?:FG|RD|X|A|)\d+)
  • (产品名称)-(PAF/PA-#)-(修订版)
  • (\w(?:\w*(?:-|\s|_)?\w+)*)(-PA(?:F|)-\d+)(-(?:FG|RD|X|A |)\d+)
  • (产品名称)-(修订版)(表号)
  • (\w(?:\w*(?:-|\s|_)?\w+)*)(-(?:FG|RD|X|A|)\d+)(?:(?:\s |-)工作表(?:\s|-)\d+)
  • (产品名称)-(修订版)
  • (\w(?:\w*(?:-|\s|_)?\w+)*)(-(?:FG|RD|X|A|)\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)

上述字符串应与正则表达式匹配。

4

2 回答 2

1

在新示例之后编辑

为了避免正则表达式模式过于复杂(这已经足够了),我会首先摆脱“工作表”部分。

因此,首先,在应用匹配指令之前从文件名中删除“sheet #”模式。

这只会将您的案例减少到这些模式:

  • (产品名称)-(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
于 2019-05-16T08:47:51.860 回答
0

在用正则表达式练习了很多之后,在 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')

于 2019-05-21T13:47:09.290 回答