我正在使用Python 2.x中的正则表达式捕获缩写的子集。以下文字中出现了几个这样的缩写:
# text # desired capture
The certolizumab pegol (Cmzia, CZP)... 'CZP'
The drug 6-mercatopureine (6-mp) ... '6-mp'
The merits of 5-Asasdfdsf (5-ASA) ... '5-ASA'
在第一个示例中,我有兴趣将结果返回CZP
并忽略Cmzia,
。
这是我之前的正则表达式,这对于匹配(6-mp)
和(5-ASA)
等案例是必要的:
\((\S*[A-Z-0-9]\S*)\) # captures '6-mp' and '5-ASA', respectively
这是我为处理上述案件所做的补充:
\S*\s+[A-Z-0-9]+ # I only want to capture the '[A-Z-0-9]+'
我尝试使用以下正则表达式(我试图加粗感兴趣的部分,以便它不会与上下文混淆,但这似乎不起作用):
# in p1, I add the pattern to the list, separated by '|'
>>> p1 = re.compile(r'\((\S*[A-Z-0-9]\S*|\S*\s+[A-Z-0-9]+)\)')
>>> p1.findall('The certolizumab pegol (Cmzia, CZP)')
['Cmzia, CZP']
# in p2, I use a broad non-capturing group, enclosing the desired captured expressions in parentheses
>>> p2 = re.compile(r'\((?:(\S*[A-Z-0-9]\S*)|\S*\s+([A-Z-0-9]+))\)')
>>> p2.findall('The certolizumab pegol (Cmzia, CZP)')
[('', '', 'CZP')]
# this is an addition to the original post
# demonstrates that the non-capturing expression doesn't prevent capture of the section \S*\s+
>>> p3 = re.compile(r'\((\S*[A-Z-0-9]\S*|(?:\S*\s+)[A-Z-0-9]+)\)')
>>> p3.findall('The certolizumab pegol (Cmzia, CZP)')
['Cmzia, CZP']
理想情况下,我想要输出CZP
。 p1 返回太多,因为我想要排除\S*\s+
对应的Cmzia,
。关于 p2 ,我知道我可以轻松地操作输出以匹配我想要的输出,但我想知道是否有办法修改正则表达式来处理它。
谢谢,如果您需要其他详细信息/说明,请与我们联系。
修改
我仍然希望正则表达式从正则表达式的第一个/原始部分捕获6-mp
和5-ASA
。
编辑2:
这包括在上面,但是把它放在一个位置并总结我的问题。
pattern = r'???'
p = re.compile(pattern)
p.findall('Stuff stuff (Cmzia, CZP) stuff stuff (5-ASA) (6-mp) stuff...')
['CZP','5-ASA','6-mp']
答案 0 :(得分:1)
这是我为实现目标而发现的最简单的正则表达式:
>>> p = "\((?:\S*,\s+)?(\S*)\)"
>>> s = "The cert pegol (Cmzia, CZP) some words (6-mp) and (5-ASA)"
>>> re.findall(p,s)
['CZP', '6-mp', '5-ASA']
<强>更新强>
下一个限制性更强,但结果相同:
>>> p = "\((?:\S*,\s+)?(\S*[A-Z-0-9]\S*)\)"
答案 1 :(得分:0)
我不太明白你想要什么,但我在对应于'CZP'的部分周围添加了另一个匹配的括号,并使外部组不匹配,并得到了这个:
>>> p3 = re.compile(r'\((?:\S*[A-Z-0-9]\S*|[A-Z-0-9]* [A-Z-0-9]*|(?:\S*\s+)([A-Z-0-9]+))\)')
>>> p3.findall('The certolizumab pegol (Cmzia, CZP)')
['CZP']
答案 2 :(得分:0)
如果我正确地读你,括号内可以有一个或两个以逗号分隔的值。如果它是两个,你只想捕获第二个。试试这个:
p = re.compile(r'\((?:[^,)]+,\s*)?([A-Za-z0-9-]+)\)')
在打开paren之后,(?:[^,)]+,\s*)?
尝试匹配第一个值,它通过尾随逗号的存在来识别。只要其中没有逗号,您就不关心第一个值是什么样的。但是你不能只使用[^,]+
因为在只有一个值的情况下这会匹配太多。将paren添加到排除字符列表中会使匹配包含在一组括号中。