我有一个过于复杂的正则表达式,据我所知是正确的
route = r"""[s+|(][iI](.)?[vV](.)?(W|s|$)?
|s intravenously|s intravenous
|[s|(][pP](.)?[oO](.)?(W|s|$)
|s perorally|s?(per)?oral(ly)?|s intraduodenally
|[s|(]i(.)?p(.)?(W|s|$)?
|s intraperitoneal(ly)?
|[s|(]i(.)?c(.)?v(.)?(W|s|$)?
|s intracerebroventricular(ly)?
|[s|(][iI](.)?[gG](.)?(W|s|$)?
|s intragastric(ly)?
|[s|(]s(.)?c(.)?(W|s|$)?
|subcutaneous(ly)?(s+injection)?
|[s|(][iI](.)?[mM](.)?(W|s|$)?
|sintramuscular
"""
使用re.search
,如果它是字符串,我设法获得众多模式之一
s = 'Pharmacokinetics parameters evaluated after single IV or IM'
m = re.search(re.compile(route, re.X), s)
m.group(0)
' IV '
我在别的地方读到使用re.findall
来找到所有的事件。在我的梦里,这将返回:
['IV', 'IM']
结果是:
[('',
'',
' ',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
''),
('',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'')]
对于您显示的摘录:
b
(?: i
(?: ntra
(?: cerebroventricular (?:ly)?
| duodenally
| gastric (?:ly)?
| muscular
| peritoneal (?:ly)?
| venous (?:ly)?
) b
| .? (?: [gmpv] | c .? v ) b .?
)
|
(?:per)? oral (?:ly)? b
|
p .? o b .?
|
subcutaneous (?:ly)? (?: s+ injection )? b
)
演示建议:
- 你有一个很长的模式,你已经使用了re.X选项,这是一件好事,通过以严格和可读的方式格式化模式来最大限度地利用它。最后,使用字母顺序。这听起来可能很傻,但这确实节省了时间!也可以添加以
#
开头的内联注释。 - 在两种不同的情况下,你有许多具有相同字符的字符类=>也使用全局re.I标志,并以小写书写模式。
- 我看到你试图用
s
或丑陋的[s|(]
(你不需要在字符类中转义括号,|
并不意味着它里面的or)和(W|s|$)?
(这是完全无用的,因为你使它可选)来划分子字符串。忘记它,使用单词边界b
(阅读它以更好地理解在哪些情况下它匹配)。 - 使用
re.findall
代替或re.search,因为您希望在单个字符串中有多个匹配。 - 使用非捕获组
(?: ... )
代替捕获组( ... )
。(当模式包含捕获组时,re.findall
只返回捕获组的内容,而不是整个匹配)。 - 从左分解模式(从左到右测试模式,从左分解减少了要测试的分支的数量)。考虑到这一点,子模式
(?:per)? oral (?:ly)? b | p .? o b .?
可以这样重写:oral (?:ly)? b | p (?: eroral (?:ly)? b | .? o .?)
- 你也可以从右边因式分解在可能的情况下。这不是一个很大的改进,但它减少了模式大小。
use (?:.)?在单词模式中找一个句号或一个句号。注意我找到了ip或ip.模式匹配不排除模式中的模式,例如ip在POip旁边。
print ("查找带或不带句点的单词组合")
data="single intravenously intravenous IV oral PO intraperitoneal intraperitoneally i.p. ip"
matches=re.findall(r'[iI](?:.)?[vV](?:.)?|intravenous(?:ly)?|[pP](?:.)?[oO](?:.)?|peroral(?:ly)?|oral(?:ly)?|[iI](?:.)?[pP](?:.)?|intraperitoneal(?:ly)?',data)
print(matches)
输出:
['intravenously', 'intravenous', 'IV', 'oral', 'PO', 'intraperitoneal', 'intraperitoneally', 'i.p.', 'ip']