【问题标题】:Substring extraction with pandas / regex使用熊猫/正则表达式提取子字符串
【发布时间】:2018-08-28 02:31:56
【问题描述】:

我正在尝试使用内置的 pandas 方法 .str.extract 从我已导入的数据框中的列中提取子字符串。列中的条目都遵循这种结构:

x.xx% Test1 Test2 Test3 XYZ|ZYX Oct 2018

所以本质上它始终是一个浮点 %,后跟一个字符串(单词的长度并不总是相同),后跟一个三字母代码,即 XYZ 或 ZYX 以及之后的日期。

我正在尝试从上面的示例中提取 Test1、Test2 和 Test3,这意味着我想去掉开头的百分比,并且在 XYZ|ZYX 出现的地方我想要所有的东西(包括三个字母代码) .

我整个上午都在阅读正则表达式,但我正在努力使用 pandas 提取物构建一些代码,这些代码可以准确地提取出我想要的内容。有什么建议?我得到的最远的是下面的,它只从一开始的百分比中提取(试图将它分成三类):

.str.extract('(\d\.\d+%.)') 

【问题讨论】:

    标签: python regex string pandas


    【解决方案1】:

    您可以使用带有前瞻的模式来确定何时停止匹配。

    ([\w\s]+?)(?=\w{3}\|)'
    

    详情

    (               # first capture group
        [\w\s]+?    # match letters or whitespaces
    )
    (?=             # lookahead
        \w{3}       # fixed length 3 chars
        \|          # literal `|`
    )
    

    s = pd.Series(['x.xx% Test1 Test2 Test3 XYZ|ZYX Oct 2018'])
    s.str.extract(r'([\w\s]+?)(?=\w{3}\|)', expand=False)
    
    0     Test1 Test2 Test3 
    dtype: object
    

    【讨论】:

      【解决方案2】:

      一个正则表达式,你可以是:

      r"(\d\.\d+%.)(.*)\s([A-Z]{3})\s([A-Z]{1}[a-z]{2})\s([0-9]{4}$)"
      

      \d\.\d+%. 匹配百分比

      [A-Z]{3} 匹配字母代码

      [A-Z]{1}[a-z]{2} 匹配月份

      [0-9]{4}$ 匹配年份,在末尾​​p>

      .* 匹配其余的,因此是测试。

      \s 匹配一个空格,它在匹配之外。

      生成的代码可能是这样的:

      import re
      
      string = "3.14% Test1 Test2 Test3 XYZ Oct 2018"
      
      matches = re.findall(r"(\d\.\d+%.)(.*)\s([A-Z]{3})\s([A-Z]{1}[a-z]{2})\s([0-9]{4}$)", string)[0]
      
      percentage = matches[0] 
      mytest = matches[1].split(' ')
      letter_code = matches[2]
      month = matches[3]
      year = matches[4]
      
      
      print(percentage) # 3.14%
      print(mytest) # ['Test1', 'Test2', 'Test3']
      print(letter_code) # XYZ
      print(month) # Oct
      print(year) # 2018
      

      【讨论】:

        【解决方案3】:

        您可以尝试积极的向后看:

        import re
        pattern=r'(?<=%)(\s.+)?XYZ|ZYX'
        text="""x.xx% Test1 Test2 Test3 XYZ|ZYX Oct 2018
        
        
        x.xx% Test1 Test2 Test3 ZYX|XYZ Oct 2018"""
        
        for i in re.findall(pattern,text):
            data=re.sub(re.escape('ZYX|'),' ',i)
            if data.split():
                print(data.split())
        

        输出:

        ['Test1', 'Test2', 'Test3']
        ['Test1', 'Test2', 'Test3']
        

        【讨论】:

          猜你喜欢
          • 2019-06-16
          • 2017-07-18
          • 2017-12-08
          • 2018-03-31
          • 1970-01-01
          • 1970-01-01
          • 2021-03-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多