【问题标题】:Why positive lookahead is working but negative lookahead doesn't?为什么积极的前瞻有效,而消极的前瞻却没有?
【发布时间】:2020-02-05 03:25:40
【问题描述】:

首先,正则表达式需要同时适用于 python 和 PCRE(PHP)。我试图忽略正则表达式模式后跟字母“x”以区分维度和下面给定示例中的“数字/数字”等字符串:

dummy word 222/2334; Ø14 x Ø6,33/523,23 x 2311 mm

从这里,我试图提取222/2334,但不是6,33/523,23,因为这部分实际上是维度的一部分。到目前为止,我想出了这个正则表达式

((\d*(?:,?\.?)\d*(?:,?\.?))\s?\/\s?(\d*(?:,?\.?)\d*(?:,?\.?)))(?=\s?x)

它可以提取我不想提取的内容,它看起来像this。如果我将积极的前瞻性更改为消极的,它会捕获它们两个,除了来自6,33/523,23 的最后一个“3”。它看起来像this。我怎样才能只捕获222/2334?我在这里做错了什么?

期望的输出:

222/2334

我得到了什么

222/2334 6,33/523,2

【问题讨论】:

  • 我的意思是......它并不漂亮,但适用于两种语言:(?!\d+(?:[,.]\d+)?\s?\/\s?\d+(?:[,.]\d+)?(?=\s?x))(\d+(?:[,.]\d+)?)\s?\/\s?(\d+(?:[,.]\d+)?)。或者,您可以在 python 中使用 (\d+(?:[,.]\d+)?+)\s?\/\s?(\d+(?:[,.]\d+)?+)(?!\s?x) 和 regex 模块来支持所有格量​​词
  • 哇...这么快?你能解释一下吗? @ctwheels
  • 最后一位数字与正则表达式 \s?x 不匹配,因此当它与该数字之前的数字匹配时满足负前瞻。
  • 根据你的具体例子,(^| )(\d+)\/(\d+)($|;) 可以工作

标签: python regex python-3.x


【解决方案1】:

您可以使用这个带有负前瞻的简化正则表达式:

((\d*(?:,?\.?)\d*(?:,?\.?))\s?\/\s?(\d*(?:,?\.?)\d*(?:,?\.?)))\b(?![.,]?\d|\s?x)

Updated RegEx Demo

  • 最后使用单词边界以避免匹配部分数字很重要(正则表达式匹配到一个数字之前的原因)

  • 还在负前瞻条件中包含 [.,]?\d,以便匹配不会在最后一个逗号之前的位置结束。


这个更短(更高效)的正则表达式也可能适用于 OP:

(\d+(?:[,.]\d+)*)\s*\/\s*(\d+(?:[,.]\d+)*)\b(?![.,]?\d|\s?x)

RegEx Demo 2

【讨论】:

  • 较短的正则表达式在浮点数方面存在一些问题。它不能匹配像 2222,232/233,4 这样的浮点数
  • 它也会匹配2222,232/233,4。我的正则表达式中有错字,在\d 之后错过了+。应该是(\d+(?:[,.]\d+)*)\s*\/\s*(\d+(?:[,.]\d+)*)\b(?![.,]?\d|\s?x)
  • 是的,它现在正在工作。谢谢你。最后一个问题(我知道这要求太多了)。我正在尝试将此正则表达式模式设为可选。我正在添加另一种模式来捕获这些部分旁边的尺寸。但是由于某种原因,它并没有变得可选,而是变得像模式一样“必要”,我的意思是,如果您的正则表达式不匹配,它就不会捕获维度。为了使其可选,我将您的正则表达式放在() 之间并在其旁边添加.*?。
  • 我有点不清楚。我建议您发布一个带有示例的新问题,以便我更好地理解它并尝试提供解决方案。
【解决方案2】:

有两个简单的选项。

第一个选项丑陋且冗长,但基本上否定了x后跟的字符串上的正匹配,然后匹配没有它的模式。

(?!PATTERN(?=x))PATTERN

See regex in use here

(?!\d+(?:[,.]\d+)?\s?\/\s?\d+(?:[,.]\d+)?(?=\s?x))(\d+(?:[,.]\d+)?)\s?\/\s?(\d+(?:[,.]\d+)?)

第二个选项使用所有格量词,但您必须在 python 中使用 regex 模块而不是 re。

See regex in use here

(\d+(?:[,.]\d+)?+)\s?\/\s?(\d+(?:[,.]\d+)?+)(?!\s?x)

另外,我将您的子模式更改为\d+(?:[,.]\d+)?。这将匹配一位或多位数字,然后可选择匹配. 或,,后跟一位或多位数字。

【讨论】:

  • 第二个正则表达式在 regex101 上抛出错误,如果风味设置为 python,但第一个在 PHP 和 python 上都有效。
  • @MehmedB 是的,这就是为什么我指定你必须使用Pypi regex module 而不是re
  • 现在我明白了。我明天测试一下。这看起来很有希望。
  • 您确实给出了几乎完美的答案,但@anubhava 的答案适用于 re 库(开箱即用)。我必须选择它作为答案。还是谢谢你。
猜你喜欢
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-17
  • 1970-01-01
相关资源
最近更新 更多