我尝试用一个独特的正则表达式来捕捉
either: ' PIC S9(17).' # with 'S9(17)' in Named Capture Group pic
either: ' PIC S9(13)V9(2).' # with 'S9(13)V9(2)' in Named Capture Group pic
either: ' PIC S9(9)V9(2) COMP-3.' # with 'S9(9)V9(2)' in Named Capture Group pic
either: ' PIC X(16).' # with 'X(16)' in Named Capture Group pic使用r'\s*PIC\s+(?P<pic>\S+)'时,除了‘PIC S9(9)V9(2) COMP-3’之外,我什么都能捕捉到。
使用r'\s*PIC\s+(?P<pic>\S+) COMP-3',我只捕获了‘PIC S9(9)V9(2) COMP-3’。
这是我的Python代码:
import re
def get_pics(data, pic):
base = r'^(?P<level>\d{2})\s+(?P<name>\S+)'
end = r'\.$'
pformat = "({})?"
pattern = re.compile(base + pformat.format(pic) + end)
for row in data.strip().split('\n'):
re_match = pattern.match(row.strip())
if not re_match:
print(' => NOP:\n ', row)
else:
match = re_match.groupdict()
print('ok:', match)
data = """
12 M-AR03-MONTANT-RDJ PIC S9(17).
12 M-AR03-COMPTE-RDJ PIC X(8).
09 M-N014-INC-CHARG-AMT-FSOL PIC S9(9)V9(2) COMP-3.
09 M-N014-CHARGE-TYPE-FSOL PIC X(5).
"""所以我们得到:
>>> get_pics(data, r'\s*PIC\s+(?P<pic>\S+)')
ok: {'level': '12', 'name': 'M-AR03-MONTANT-RDJ', 'pic': 'S9(17)'}
ok: {'level': '12', 'name': 'M-AR03-COMPTE-RDJ', 'pic': 'X(8)'}
=> NOP:
09 M-N014-INC-CHARG-AMT-FSOL PIC S9(9)V9(2) COMP-3.
ok: {'level': '09', 'name': 'M-N014-CHARGE-TYPE-FSOL', 'pic': 'X(5)'}
>>>或
>>> get_pics(data, r'\s*PIC\s+(?P<pic>\S+) COMP-3')
=> NOP:
12 M-AR03-MONTANT-RDJ PIC S9(17).
=> NOP:
12 M-AR03-COMPTE-RDJ PIC X(8).
ok: {'level': '09', 'name': 'M-N014-INC-CHARG-AMT-FSOL', 'pic': 'S9(9)V9(2)'}
=> NOP:
09 M-N014-CHARGE-TYPE-FSOL PIC X(5).
>>>奇怪的是,在https://regex101.com/中,'\s*PIC\s+(?P<pic>\S+)'匹配所有4行代码:
PIC S9(17).
PIC S9(13)V9(2).
PIC S9(9)V9(2) COMP-3.
PIC X(16).如果我尝试@ the -fourth bird正则表达式,我会得到:
In [2]: get_pics(data, r'\bPIC (?P<pic>(?:[A-Z]\d*\(\d+\))+)[^.\r\n]*\.')
...:
=> NOP:
12 M-AR03-MONTANT-RDJ PIC S9(17).
=> NOP:
12 M-AR03-COMPTE-RDJ PIC X(8).
=> NOP:
09 M-N014-INC-CHARG-AMT-FSOL PIC S9(9)V9(2) COMP-3.
=> NOP:
09 M-N014-CHARGE-TYPE-FSOL PIC X(5).
In [3]: 发布于 2020-02-17 01:33:21
如果您希望使用这些值捕获组pic,并且在末尾应该有一个点,那么可以使模式更具体一些:
\bPIC (?P<pic>(?:[A-Z]\d*\(\d+\))+)[^.\r\n]*\.\bPIC单词边界,匹配数字和space(?P<pic>命名组(?:非捕获组[A-Z]\d*\(\d+\)在parenthesis之间匹配字符A-Z、操作位和PIC pic 1+
- `)+` Close group an repeat 1+ times
) Close group pic[^.\r\n]*\.匹配除点和换行符0+时间以外的任何字符,并匹配尾随的点在您的代码中,不必使用?将组设为可选组pic的模式已经包含与结束点匹配的模式,因此您可以省略end = r'\.$'
在第一个和第二个模式之间,您可以使用[^\S\r\n]+匹配一个或多个空格,它将匹配除换行符以外的1倍或更多倍的空格字符。
例如
import re
def get_pics(data, pic):
base = r'(?P<level>\d{2})\s+(?P<name>\S+)'
pattern = re.compile(f"^{base}[^\S\r\n]+{pic}$")
for row in data.strip().split('\n'):
re_match = pattern.match(row.strip())
if not re_match:
print(' => NOP:\n ', row)
else:
match = re_match.groupdict()
print('ok:', match)
data = """
12 M-AR03-MONTANT-RDJ PIC S9(17).
12 M-AR03-COMPTE-RDJ PIC X(8).
09 M-N014-INC-CHARG-AMT-FSOL PIC S9(9)V9(2) COMP-3.
09 M-N014-CHARGE-TYPE-FSOL PIC X(5).
"""
get_pics(data, r'\bPIC (?P<pic>(?:[A-Z]\d*\(\d+\))+)[^.\r\n]*\.')输出
ok: {'level': '12', 'name': 'M-AR03-MONTANT-RDJ', 'pic': 'S9(17)'}
ok: {'level': '12', 'name': 'M-AR03-COMPTE-RDJ', 'pic': 'X(8)'}
ok: {'level': '09', 'name': 'M-N014-INC-CHARG-AMT-FSOL', 'pic': 'S9(9)V9(2)'}
ok: {'level': '09', 'name': 'M-N014-CHARGE-TYPE-FSOL', 'pic': 'X(5)'}发布于 2020-02-17 01:38:38
考虑到您的有限示例,我不明白为什么以下内容还不够:
r'\sPIC\s((?:(?:[SV]\d|X))?\((?:\d+)\))+( COMP-3)?\.'例如,如果示例中始终只有1个空格,则不需要使用\s+。
同样,如果您不告诉我们该位是如何变化的,那么在正则表达式中没有理由不使用文字COMP-3 (例如,它是COMP-后跟任意数字的整数?好吧,好吧,使用COMP-\d+)。
发布于 2020-02-17 02:24:14
我修改了你的基本模式,在最后加入了空格,并为pic设计了一个不同的模式。
pat2 = r'(?P<level>\d{2})\s+(?P<name>\S+)\s+'
picpat = r'PIC\s(?P<pic>[^.\s]+)'picpat匹配'PIC '之后的任何内容,直到它到达一个点或空格。

我使用f字符串对函数进行了一些修改,将其与pic模式相结合,迭代匹配而不是行。
def get_pics(data,pic):
pat2 = r'(?P<level>\d{2})\s+(?P<name>\S+)\s+'
pattern = f'{pat2}{pic}'
#pattern = '{}{}'.format(pat2,pic)
pattern = re.compile(pattern)
for match in pattern.finditer(data):
print(match.groupdict())
>>> get_pics(data,picpat)
{'level': '12', 'name': 'M-AR03-MONTANT-RDJ', 'pic': 'S9(17)'}
{'level': '12', 'name': 'M-AR03-COMPTE-RDJ', 'pic': 'X(8)'}
{'level': '09', 'name': 'M-N014-INC-CHARG-AMT-FSOL', 'pic': 'S9(9)V9(2)'}
{'level': '09', 'name': 'M-N014-CHARGE-TYPE-FSOL', 'pic': 'X(5)'}
>>> https://stackoverflow.com/questions/60251161
复制相似问题