正则表达式X但不是Y,或Z,Pandas,Python

时间:2017-10-31 10:52:59

标签: python regex pandas

我需要一个提取四位或三位数字标识符的正则表达式,并排除2013 - 2017年的潜在年份。

源数据可能如下所示:

1011 & 1012 - Mcdonalds - 2015 year 
433,434,4356 - Burger king - 2016

因此,输入数据的方法可能会有所不同。不需要2013-2017,可以忽略。

我目前的正则表达式是'(\d\d\d\d[^2013-2017]|\d\d\d)'

这些年份显然不会出现在3位数字标识符中,因此它只适用于4位数字标识符。

简而言之,2013 - 2017年的参赛作品仍然存在。正则表达式应用于下面的行。它被命名为变量,所以我可以在Spyder的变量资源管理器中看到它。

cif_regex= '(\d\d\d\d[^2013-2017]|\d\d\d)'
variable = frame["Filename"].str.extractall(cif_regex)

我一直在玩不同的正则表达式,但显然不能理解它以正确表达它。

2 个答案:

答案 0 :(得分:3)

您需要使用否定前瞻并使用单词边界(至少)锚定匹配:

\b((?!201[3-7])\d{4}|\d{3})\b

请参阅regex demo

如果匹配也在数字字符之外(例如,在_或字母内),请使用否定(?<!\d) / (?!\d)外观而不是字边界:

(?<!\d)((?!201[3-7])\d{4}|\d{3})(?!\d)
^^^^^^^                         ^^^^^^

请参阅another regex demo

<强>详情

  • (?<!\d) - 如果当前位置左侧有一个数字(或\b - 一个前导词边界),则会导致匹配失败的负面后视镜
  • ( - 第1组开始:
    • (?!201[3-7])\d{4} - 除20132014201520162017
    • 以外的任何4位数字
    • |
    • \d{3} - 3位数
  • ) - 第1组结束
  • (?!\d) - 如果当前位置右侧有一个数字(或\b - 一个尾随字边界),则会导致匹配失败的否定前瞻

在Python中(注意将r''前缀解析为\b作为单词边界而不是作为退格字符):

cif_regex= r'\b((?!201[3-7])\d{4}|\d{3})\b'
variable = frame["Filename"].str.extractall(cif_regex)

答案 1 :(得分:1)

你可以在正则表达式中使用负前瞻和后瞻断言,但我认为一个更简单的解决方案是首先匹配所有3位和4位数字,然后根据你的年份范围进行过滤。

>>> t = "1011 & 1012 - Mcdonalds - 2015 year \n433,434,4356 - Burger king - 2016"
>>> [m for m in re.findall(r'\d{3,4}', t) if int(m) not in range(2013, 2018)]
['1011', '1012', '433', '434', '4356']