我有一个大型的CT扫描结果和印象数据库。我试图构建一个正则表达式,该表达式搜索整数或浮点数,后面跟着“mm”,它与前面或后面的单词‘结节’相邻。到目前为止,这是我所拥有的正则表达式:
nodule_4mm_size = "(?s).*?([0-4]*\.*[0-9]+\s*[mM]{2})[\w\W]{0,24}[Nn]odule|(?s)[Nn]odule[\w\W]{0,24}.*?([0-4]*\.*[0-9]+\s*[mM]{2})”
然而,我需要确保这些调查结果之前没有之前或之前的测量。放射学家指的是以前的扫描。所以我试着做一个负面的回顾,像这样:
(?<!previously measured)\?[Nn]odule[\w\W]{0,24}[^\.\d]([0-4]\s*[mM]{2}|[0-3]\.[0-9]\s*[mM]{2}|4\.0+\s*[mM]{2})
但是,我不能让它起作用。以下面的段落为例。
例如,最大的结节位于右下叶,目前为4.4毫米(图#82,系列3),此前曾在2011年01月09/01测量过3.6毫米。
在这种情况下,我想正则击中4.4毫米,而不是3.6毫米。此外,如果找到多个点击,我只想保持最大的大小找到。例如,
“例如,最大的结节位于右下叶,目前为4.4毫米(图#82,系列3),曾于2011年01月09/01测得3.6毫米,另一个结节为2.2毫米。
在这种情况下,我想确保只有4.4毫米是确定的。
任何帮助都是非常感谢的。只是不能让这种消极的眼光去工作!谢谢!
发布于 2015-09-21 22:56:18
让我们把它分解,保留相关的部分。到目前为止,您有两个选择:
选项1 (数字后面跟着"nodule
"):
([0-4]\.\d+\s*[mM]{2})[\s\S]{0,24}[Nn]odule
选项2 ("nodule
“后面跟着数字):
[Nn]odule[\s\S]{0,24}([0-4]\.\d+\s*[mM]{2})
您应该知道regex引擎是贪婪。这意味着[\s\S]{1,24}
将尽可能多地匹配,匹配不一定与"nodule
“最接近的数字。例如,
Pattern: [Nn]odule[\s\S]{0,24}([0-4]\.\d+\s*[mM]{2})
Text: ... nodule measured 1.4 mm. Another 3.2 mm ...
^ ^
| |
matches this second occurence. +----+
要解决这个问题,在量词后面添加一个额外的?
,使其成为懒惰。因此,不要使用[\s\S]{0,24}
,而是使用[\s\S]{0,24}?
。
例如,最大的结节位于右下叶,目前为4.4毫米。
这里的示例有"nodule
“,由超过24个字符分隔。您应该增加两者之间的字符数。也许是[\s\S]{0,70}?
。
所以我正在尝试一个消极的方法
后面只断言位于某个位置之前的文本。为了避免这种情况,我建议与文本"previously measured
“相匹配,使用它周围的一些字符。你怎么知道不考虑这些案子?简单,不要制造捕捉。所以你会匹配一些类似的
[\s\S]{0,10}previously measured[\s\S]{0,10}
并放弃比赛,因为它没有返回任何组。此外,您可以在这里包括不同的例外:
[\s\S]{0,10}(?:previously measured|previous scan|another patient|incorrectly measured)[\s\S]{0,10}
如果找到多个点击量,我只想保持最大的大小。
你不能用regex那样做。循环在您的代码中查找最大的。
结果:
在这些条件下,我们有:
[\s\S]{0,10}previously measured[\s\S]{0,10}|([0-4]\.\d+\s*[mM]{2})[\s\S]{0,70}?[Nn]odule|[Nn]odule[\s\S]{0,70}?([0-4]\.\d+\s*[mM]{2})
需要检查的额外条件
也许,为了减少误报,以下选项之一很有用:
nodule
“和数字之间有一个句号,就不要匹配。发布于 2015-09-21 22:36:08
有两种可能性:
1)使用查找器:
(?<!previously measured )(?<![0-9.])([0-9]+(?:\.[0-9]+)?) ?mm
第一个检查"previously measured "
是否在数字之前,第二个检查数字之前是否没有数字或点(否则点后面的4个将匹配)。请记住,regex引擎返回左边的第一个结果)。
2)使用捕获组:
previously measured [0-9]+(?:\.[0-9]+)? ?mm|([0-9]+(?:\.[0-9]+)?) ?mm
这样做的目的是为了与你之前想要避免的东西相匹配。当捕获组1存在时,您将得到一个结果。
对于最大的数字,使用re.findall
方法,然后取最大的结果(正则表达式不能解决这类事情)。
发布于 2015-09-21 22:48:19
如果需要在附近有nodule
单词,您可以尝试使用:
(?:((?<!previously measured\s)\d+.\d+\s*mm)(?:[^.?!\n]*?)?nodule|nodule(?:[^.?!\n]*?((?<!previously measured\s)\d+.\d+\s*mm))?)
如果:
[^.?!\n]
应该防止它,不管像先生这样的词,小数等会干扰匹配),你可以用.+?
(演示)代替它,但是它可以在句子之间匹配。其他类似的解决办法是:
(?=((?<!previously measured\s)\d+.\d+ mm)[^.?!]+nodule)|(?=nodule[^.?!]+((?<!previously measured\s)\d+\.\d+ mm))
仅基于旁观者,它将不直接匹配文本,而是零长位置,并将捕获值成组。
https://stackoverflow.com/questions/32704676
复制相似问题