如何在Python中使用正则表达式从字符串中提取数字,除非在括号内?

时间:2015-04-28 10:40:03

标签: python regex

以下是我的测试字符串:

  • 单词单词;的 123-125
  • 单词(1000-1000)
  • 单词单词(1000-1000);的 99-999
  • 单词单词word

我应该使用什么正则表达式来仅提取不在括号内的那些数字(格式:\d+-\d+(上面以粗体显示的那些)?

我试过这个:

(\d+-\d+)(?!\))

但它匹配:

  • 单词单词;的 123-125
  • 单词( 1000-100 0)
  • 单词单词( 1000-100 0);的 99-999
  • 单词单词word

注意第二个括号前的最后一位数字。

我试图放弃任何后面跟一个支架的比赛,但它只丢掉一个数字而不是整个比赛!我在这里缺少什么?

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:5)

您可以使用否定预测来获取您需要的值,如下所示:

(?![^()]*\))(\d+-\d+)

(?![^()]*\))前瞻实际检查连字号后面没有关闭圆括号。

请参阅demo

示例代码:

import re
p = re.compile(ur'(?![^()]*\))(\d+-\d+)')
test_str = u"Word word word; 123-125\nWord word (1000-1000)\nWord word word (1000-1000); 99-999\nWord word word word"
re.findall(p, test_str)

sample program的输出:

[u'123-125', u'99-999'] 

答案 1 :(得分:2)

一种方法是描述您不想要的所有内容:

[^(\d]*(?:\([^)]*\)[^(\d]*)*

然后你可以使用一个始终正确的断言:一个数字前面总是有零个或多个不是数字和引号之间字符的字符。

您只需要捕获组中的数字:

p = re.compile(r'[^(\d]*(?:\([^)]*\)[^(\d]*)*(\d+-\d+)')

这种方式的优点是您不需要在字符串中的每个位置测试前瞻,因此它是一种快速模式。不方便的是它消耗了更多的内存,因为整个匹配会产生更长的字符串。