首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python Regex负查找

Python Regex负查找
EN

Stack Overflow用户
提问于 2015-09-21 21:14:31
回答 4查看 283关注 0票数 1

我有一个大型的CT扫描结果和印象数据库。我试图构建一个正则表达式,该表达式搜索整数或浮点数,后面跟着“mm”,它与前面或后面的单词‘结节’相邻。到目前为止,这是我所拥有的正则表达式:

代码语言:javascript
运行
复制
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})”

然而,我需要确保这些调查结果之前没有之前或之前的测量。放射学家指的是以前的扫描。所以我试着做一个负面的回顾,像这样:

代码语言:javascript
运行
复制
(?<!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毫米是确定的。

任何帮助都是非常感谢的。只是不能让这种消极的眼光去工作!谢谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-09-21 22:56:18

让我们把它分解,保留相关的部分。到目前为止,您有两个选择:

选项1 (数字后面跟着"nodule"):

代码语言:javascript
运行
复制
([0-4]\.\d+\s*[mM]{2})[\s\S]{0,24}[Nn]odule

选项2 ("nodule“后面跟着数字):

代码语言:javascript
运行
复制
[Nn]odule[\s\S]{0,24}([0-4]\.\d+\s*[mM]{2})

您应该知道regex引擎是贪婪。这意味着[\s\S]{1,24}将尽可能多地匹配,匹配不一定与"nodule“最接近的数字。例如,

代码语言:javascript
运行
复制
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“相匹配,使用它周围的一些字符。你怎么知道不考虑这些案子?简单,不要制造捕捉。所以你会匹配一些类似的

代码语言:javascript
运行
复制
[\s\S]{0,10}previously measured[\s\S]{0,10}

并放弃比赛,因为它没有返回任何组。此外,您可以在这里包括不同的例外:

代码语言:javascript
运行
复制
[\s\S]{0,10}(?:previously measured|previous scan|another patient|incorrectly measured)[\s\S]{0,10}

如果找到多个点击量,我只想保持最大的大小。

你不能用regex那样做。循环在您的代码中查找最大的。

结果:

在这些条件下,我们有:

代码语言:javascript
运行
复制
[\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})

演示

需要检查的额外条件

也许,为了减少误报,以下选项之一很有用:

  1. 不允许在换行符后匹配。
  2. 如果"nodule“和数字之间有一个句号,就不要匹配。
  3. 找一个接近测量值的日期。
票数 1
EN

Stack Overflow用户

发布于 2015-09-21 22:36:08

有两种可能性:

1)使用查找器:

代码语言:javascript
运行
复制
(?<!previously measured )(?<![0-9.])([0-9]+(?:\.[0-9]+)?) ?mm

第一个检查"previously measured "是否在数字之前,第二个检查数字之前是否没有数字或点(否则点后面的4个将匹配)。请记住,regex引擎返回左边的第一个结果)。

2)使用捕获组:

代码语言:javascript
运行
复制
previously measured [0-9]+(?:\.[0-9]+)? ?mm|([0-9]+(?:\.[0-9]+)?) ?mm

这样做的目的是为了与你之前想要避免的东西相匹配。当捕获组1存在时,您将得到一个结果。

对于最大的数字,使用re.findall方法,然后取最大的结果(正则表达式不能解决这类事情)。

票数 1
EN

Stack Overflow用户

发布于 2015-09-21 22:48:19

如果需要在附近有nodule单词,您可以尝试使用:

代码语言:javascript
运行
复制
(?:((?<!previously measured\s)\d+.\d+\s*mm)(?:[^.?!\n]*?)?nodule|nodule(?:[^.?!\n]*?((?<!previously measured\s)\d+.\d+\s*mm))?)

演示

如果:

  • 小结节与以mm为单位的值在同一个句子中( [^.?!\n]应该防止它,不管像先生这样的词,小数等会干扰匹配),你可以用.+? (演示)代替它,但是它可以在句子之间匹配。
  • 值在word结节之前或之后(在此程序中,如果前面有值,则首先匹配),
  • 值将在组中捕获:在- \1、- \2、
  • 它应该与g和i模式一起使用。

其他类似的解决办法是:

代码语言:javascript
运行
复制
(?=((?<!previously measured\s)\d+.\d+ mm)[^.?!]+nodule)|(?=nodule[^.?!]+((?<!previously measured\s)\d+\.\d+ mm))

演示

仅基于旁观者,它将不直接匹配文本,而是零长位置,并将捕获值成组。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32704676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档