Python中的负向前查找正则表达式

1 投票
2 回答
663 浏览
提问于 2025-04-16 21:00

我在Python中写负向前查找的正则表达式时遇到了困难。这是一些示例字符串(我有超过80,000条这样的文本消息):

patient 100/64  bp is 120/90 *some string*  
100H/64 patient bp 120/90  
location 100c/64 patient bp120/90 *some string*
*some string* 100/64 patient *this string with no 'bp' value*

这里的 120/90 是指病人的血压。我只想提取 '病房#/床位#'(例如:100/64100H/64100c/64100/64),而不是血压。我无法写出负向前查找的断言,因为它需要固定长度。我的正则表达式是:

(?<!bp.*)(\b[0-9]{1,3}[a-zA-Z]?)\/([0-9]{1,3}[a-zA-Z]?\b)

这个表达式不工作,因为我在负向前查找中用了 .*,请帮我解决这个问题。

编辑:每个病人记录都是从新的一行开始的,这些记录保存在一个文本文件中,我是通过Hadoop处理得到的。血压值不一定总是在最后(或者在某些记录中可能根本没有出现),而病房/床位的值也不一定总是在开头。

2 个回答

0

在下面的解决方案中,我不关心那些编号,因为你不想捕捉它们。

这个解决方案的原理是捕捉像 '2000/478' 或 '312YXZ/17' 这样的字符串,这些字符串前面或后面都有“patient”这个词。
如果病人的编号可以在没有“patient”这个词的情况下出现,那么这个解决方案就不适用了,你需要更详细地解释一下在分析的字符串中可能遇到的情况。

import re

ch = '''patient 101/10  bp is 120/90 *some string*
297lol/27 patient
308H/38 patient bp 120/90  
location 415c/45        patient bp120/90 *some string*
*some string* 572/52 patient *this string with no 'bp' value*
a 120/90 bp for 617E/67        patient at 12:32
location 789k/79 bp120/90 *some string*'''

pat = ('(patient[ \t]+)?(\d+[a-zA-Z]*/\d+)(?(1)|[ \t]+patient)')

regx = re.compile(pat)

print [mat.group(2) for mat in regx.finditer(ch)]

结果

['101/10', '297lol/27', '308H/38', '415c/45', '572/52', '617E/67']
2

如果你的血压总是在你表达之后,那就把思路反过来,只在“bp”后面匹配。对于前瞻匹配来说,可以使用量词。

(\b[0-9]{1,3}[a-zA-Z]?)\/([0-9]{1,3}[a-zA-Z]?\b)(?=.*\bbp)

你可以在 这里查看

这意味着

(?=.*\bbp) 是一个正向前瞻,它确保字符串中有“bp”在后面。

如果你不能依赖“bp”,那么就检查在前瞻中是否有相同的模式重复出现,像这样

(\b[0-9]{1,3}[a-zA-Z]?)\/([0-9]{1,3}[a-zA-Z]?\b)(?=.*[0-9]{1,3}[a-zA-Z]?\/[0-9]{1,3}[a-zA-Z]?)

你可以在 这里查看

撰写回答