【问题标题】:RegEx for extracting certain number of chars before the last hyphenRegEx 用于在最后一个连字符之前提取一定数量的字符
【发布时间】:2019-09-29 12:55:14
【问题描述】:

您好,我想提取数据框列中的日期,日期用“-”或“to”分隔

 pop       DATE                     
 0  1.5   OWREAP-01/06/18to30/06/18  
 1  1.7   OW - 01/07/18 - 30/08/18     
 2  3.6   BCREAP - 01/08/18 to 30/08/18 
 3  2.4   BCGRA TO 01/08/18 to 30/08/18

我尝试将“to”和“TO”替换为“-”

df['DATE'].str.replace('to|TO','-')
 pop       DATE                     
 0  1.5   OWREAP-01/06/18-30/06/18  
 1  1.7   OW - 01/07/18 - 30/08/18     
 2  3.6   BCREAP - 01/08/18 - 30/08/18 
 3  2.4   BCGRA - 01/08/18 - 30/08/18

现在我需要知道如何提取最后一个连字符前后的 8 个字符 即

 pop       type   startdate enddate                    
 0  1.5   OWREAP  01/06/18  30/06/18  
 1  1.7   OW      01/07/18  30/08/18     
 2  3.6   BCREAP  01/08/18  30/08/18 
 3  2.4   BCGRA   01/08/18  30/08/18

【问题讨论】:

  • 您应该为此使用正则表达式。我将添加标签,让 regex-sharks 处理其余部分。
  • 为什么不把split 放在' - ' 上并拿走最后两项?抄送。 @AntonvBR
  • @AndrasDeak 好吧,看看原始数据帧,我们可以跳过中间步骤来替换到/TO,并通过使用正则表达式,我们确保我们得到正确格式的日期。但是,你没有错。还有其他方法可以解决。
  • r'([0-9\/]+)\s\S+\s([0-9\/]+)' 作为正则表达式字符串为我工作

标签: python regex pandas dataframe datetime


【解决方案1】:

你可以使用

reg = r'(?i).*(\d{2}/\d{2}/\d{2}(?:\d{2})?)\s*(?:TO|-)\s*(\d{2}/\d{2}/\d{2}(?:\d{2})?)'
df[['startdate','enddate']] = df.pop('DATE').str.extract(reg)

请参阅regex demo

详情

  • (?i) - 不区分大小写的标志
  • .* - 任何 0+ 个字符,尽可能多
  • (\d{2}/\d{2}/\d{2}(?:\d{2})?) - 开始日期捕获组:2 位,/,2 位,/,2 或 4 位
  • \s* - 0+ 个空格
  • (?:to|-) - to-
  • \s*
  • \s* - 0+ 个空格
  • (\d{2}/\d{2}/\d{2}(?:\d{2})?) - 结束日期捕获组:2 位,/,2 位,/,2 或 4 位

Python 测试:

df = pd.DataFrame( {'DATE': ["OWREAP-01/06/18to30/06/18"],
                    'dummy': ["value"]})
reg = r'(?i).*(\d{2}/\d{2}/\d{2}(?:\d{2})?)\s*(?:to|-)\s*(\d{2}/\d{2}/\d{2}(?:\d{2})?)'
df[['startdate','enddate']] = df.pop('DATE').str.extract(reg)
>>> df
   dummy startdate   enddate
0  value  01/06/18  30/06/18

【讨论】:

  • 这很棒,但如果它在某些情况下是“01/06/2018to30/06/2018”怎么办? “/”后面的字符数不定怎么办?
【解决方案2】:

使用splat = df.DATE.str.split(expand=True)拆分得到:

        0   1         2   3         4
0  OWREAP   -  01/06/18  to  30/06/18
1      OW   -  01/07/18   -  30/08/18
2  BCREAP   -  01/08/18  to  30/08/18
3   BCGRA  TO  01/08/18  to  30/08/18

那么splat[2] 是你的startdate 列,splat[4]enddate

【讨论】:

  • 谢谢,但如果中间没有空格,这将不起作用,我已更改帖子以反映它。
  • 好的,既然您已经知道如何将“to”转换为“-”,现在我已经向您展示了split(),请注意split() 可以选择指定分隔符特点。我相信你可以从这里拿走它。
  • ``` df2['DATE2']=df2['DATE'].str.replace('to|TO','-') df2['endDATE']=df2['DATE '].str.split('-').str[-1] df2['starDATE']=df2['DATE'].str.split('-').str[-2]```谢谢使用这个要搞清楚
猜你喜欢
  • 1970-01-01
  • 2022-11-24
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多