我有一个庞大的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})
然而,我无法让它发挥作用。以下段为例。
&#34;例如,位于右下方的最大结节 叶片和目前的尺寸为4.4毫米(图像#82,系列3) 在09/01/2011测得3.6毫米。&#34;
在这种情况下,我希望正则表达式达到4.4毫米而不是3.6毫米。此外,如果找到多个匹配,我想只保留找到的最大尺寸。例如,
&#34;例如,位于右下方的最大结节 叶片和目前的尺寸为4.4毫米(图像#82,系列3) 在09/01/2011测得3.6毫米。发现另一个结节为2.2毫米。
在这种情况下,我想确保只识别4.4毫米。
真正感谢任何帮助。只是不能让这种消极的观察能够发挥作用!谢谢!
答案 0 :(得分:1)
两种可能性:
1)使用lookbehinds:
(?<!previously measured )(?<![0-9.])([0-9]+(?:\.[0-9]+)?) ?mm
第一个检查"previously measured "
是否在数字之前,第二个检查数字之前是否没有数字或点(否则点后面的4将匹配。请记住,正则表达式引擎返回第一个结果在左边。)
2)使用捕获组:
previously measured [0-9]+(?:\.[0-9]+)? ?mm|([0-9]+(?:\.[0-9]+)?) ?mm
这个想法是为了匹配你想要避免的东西。当捕获组1存在时,您会得到一个结果。
关于最大的数字,请使用re.findall
方法并获取最大的结果(正则表达式无法解决此类问题)。
答案 1 :(得分:1)
如果附近需要nodule
个字词,您可以尝试使用:
(?:((?<!previously measured\s)\d+.\d+\s*mm)(?:[^.?!\n]*?)?nodule|nodule(?:[^.?!\n]*?((?<!previously measured\s)\d+.\d+\s*mm))?)
匹配如果:
[^.?!\n]
应该防止它,但是像先生,小数等字样会打扰
匹配),您可以将其替换为.+?
(DEMO),但它可以匹配句子其他类似的解决方案是:
(?=((?<!previously measured\s)\d+.\d+ mm)[^.?!]+nodule)|(?=nodule[^.?!]+((?<!previously measured\s)\d+\.\d+ mm))
仅基于外观,它不会直接匹配文本,而是零长度位置,并将值捕获到组中。
答案 2 :(得分:1)
让我们分解,保留相关部分。到目前为止,您有两个选择:
选项1 (数字后跟&#34; nodule
&#34;):
([0-4]\.\d+\s*[mM]{2})[\s\S]{0,24}[Nn]odule
选项2 (&#34; nodule
&#34;后跟数字):
[Nn]odule[\s\S]{0,24}([0-4]\.\d+\s*[mM]{2})
您应该知道正则表达式引擎是greedy。这意味着[\s\S]{1,24}
将尝试尽可能多地匹配,匹配不一定最接近&#34; nodule
&#34;的数字。例如,
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. +----+
要解决此问题,请在量词后添加额外的 ?
以使其成为lazy。因此,请使用[\s\S]{0,24}
。
[\s\S]{0,24}?
例如,最大的结节位于右下叶,目前尺寸为4.4 mm
这个例子有&#34; nodule
&#34;相隔超过24个字符。你应该增加两者之间的字符数。也许是[\s\S]{0,70}?
。
所以我正在尝试一种负面的背后隐藏
Lookbehinds仅断言紧靠某个位置之前的文本。为了避免这种情况,我建议使用文本&#34; previously measured
&#34;来消费它周围的一些字符。那么,你怎么知道不考虑这些案件呢?很容易,不要创建捕获。所以你会匹配像
[\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}
如果找到多个匹配,我想只保留找到的最大尺寸
你不能用正则表达式做到这一点。在代码中循环以找到最大的。
根据这些条件,我们有:
[\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
&#34;之间完全停止,请不要匹配。和数字。答案 3 :(得分:1)
关于这个问题,我最终使用nltk模块将报告标记为单个句子。适用于所有实例的最终正则表达式是:
$location.path('/search/query/' + encodeURIComponent($scope.searchTerm) );
所以在这个例子中,我最终没有做一个负面的后视,而是做了一个捕捉组。
感谢大家的意见。