【问题标题】:Regex time,date,id正则表达式时间,日期,id
【发布时间】:2020-04-14 17:52:53
【问题描述】:

我们使用相同的系统日志,并且我们想要显示方括号内的日期、时间和进程 ID。我们可以读取系统日志的每一行并将内容传递给show_time_of_pid 函数。

import re

def show_time_of_pid(line):


    pattern=r"^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec).*\d{2}:\d{2}:\d{2}\[(\d+)\]"
    result = re.search(pattern, line)

    return result

这个:

print(show_time_of_pid("Jul 6 14:01:23 computer.name CRON[29440]: USER (good_user)"))

应该打印:

Jul 6 14:01:23 pid:29440

我们在show_time_of_pid 实现中遗漏了什么?

【问题讨论】:

标签: python regex


【解决方案1】:
import re
def show_time_of_pid(line):
  pattern = r"(^\b[A-Za-z]{3}\b [1-9] \b[\d]{2}:[\d]{2}:[\d]{2}\b) [\w].*\[([\d]+)\]"
  result = re.search(pattern, line)
  return "{} pid:{}".format(result[1],result[2])

(请务必注意间距以便轻松匹配)

分解: 模式中的括号 () 是将输入字符串分成组,以便我获得索引以提取结果

  1. ^\b[A-Za-z]{3}\b :匹配前三个字母,即 jul(不是 ^ 表示以 开头,{3} 表示前 3 个匹配元素

  2. [1-9] \b[\d]{2}:[\d]{2}:[\d]{2}\b : [1-9] - 匹配单个数字 1-9 ,\b[\d]{2}:[\d]{2}:[\d]{2}\b - 完全匹配格式 xx:xx:xx 的任何时间,即 02:15:67 ,{2} - 仅表示 2 位数字

  3. [\w].*\[([\d]+)\] : [\w].* 匹配所有其他字母数字字符(注意.* 帮助所有其他匹配的单词,包括空格),\[([\d]+)\] - \d 用于数字,为什么\[ 是要完全匹配方括号,[\d]+ 也是要匹配范围内的更多数字

【讨论】:

    【解决方案2】:

    您的代码中存在一些问题:

    • [] 应该以正则表达式模式转义,因为它们是特殊符号(表示一组字符)。
    • 您没有使用组作为日期和时间,因此您以后无法从结果中得到它。
    • 您没有尝试从搜索结果中获取这些组(实际上有一个用于月份和 pid 的组)。您刚刚尝试打印搜索结果对象。

    我建议阅读有关[] 和群组的docsHOWTO 在一年中的这个时候也很棒。

    这是一个工作示例:

    import re
    
    def show_time_of_pid(line):
      pattern=r"^(?P<date_time>(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d{,2}\s+\d{2}:\d{2}:\d{2}).*\[(?P<pid>\d+)\]"
      re_result = re.search(pattern, line)
    
      result = f"{re_result.group('date_time')} pid:{re_result.group('pid')}"
    
      return result
    
    print(show_time_of_pid("Jul 6 14:01:23 computer.name CRON[29440]: USER (good_user)"))
    
    

    输出:

    Jul 6 14:01:23 pid:29440
    

    【讨论】:

      【解决方案3】:

      简单的解决方案

      def show_time_of_pid(line):
      
          date_pattern = r'\w+ \d (\d:?)+'
          date_result = re.search(date_pattern, line)
      
          pid_pattern = r'\[(\d+)\]'
          pid_result = re.search(pid_pattern, line)
      
          if date_result == None or pid_result == None :
              return "None"
      
          return '{} pid:{}'.format(date_result[0], pid_result[1])
      

      【讨论】:

        【解决方案4】:
        ^(\w+)([\d: ]+).*(\d{2}:\d{2}:\d{2}).*\[(\d+)\]
        

        我做了 4 个组,第 1 个代表月份,第 2 个代表日期,第 3 个代表时间,第 4 个代表 pid。

        【讨论】:

          【解决方案5】:

          这是我的解决方案。在引号中,第一个括号表达式是 group(1) 第二个是 group(2) 第三个是 group(3),我们只需要 group 1 和 group 3。

              import re
              def show_time_of_pid(line):
                  pattern = r"(^\w* .\d*.\d*:\d*:\d+)(.*)\[(\d+)\]"
                  result = re.search(pattern, line)
                  return "{} pid:{}".format(result.group(1), result.group(3))
          
              print(show_time_of_pid("Jul 6 14:01:23 computer.name CRON[29440]: USER (good_user)"))
          

          输出:

          7 月 6 日 14:01:23 pid:29440

          【讨论】:

            【解决方案6】:
            import re
               def show_time_of_pid(line):
                    pattern = r'^(\w+ [0-9] [0-9]+:[0-9]+:[0-9]+) [\w\.]+ [\w=]+\[([0-9]+)\]'
                    result = re.search(pattern, line)
                    return "{} pid:{} ".format(result[1], result[2])
            
              print(show_time_of_pid("Jul 6 14:01:23 computer.name CRON[29440]: USER (good_user)")) # Jul 6 14:01:23 pid:29440
            
              print(show_time_of_pid("Jul 6 14:02:08 computer.name jam_tag=psim[29187]: (UUID:006)")) # Jul 6 14:02:08 pid:29187
            
              print(show_time_of_pid("Jul 6 14:02:09 computer.name jam_tag=psim[29187]: (UUID:007)")) # Jul 6 14:02:09 pid:29187
            
              print(show_time_of_pid("Jul 6 14:03:01 computer.name CRON[29440]: USER (naughty_user)")) # Jul 6 14:03:01 pid:29440
            
              print(show_time_of_pid("Jul 6 14:03:40 computer.name cacheclient[29807]: start syncing from \"0xDEADBEEF\"")) # Jul 6 14:03:40 pid:29807
            
              print(show_time_of_pid("Jul 6 14:04:01 computer.name CRON[29440]: USER (naughty_user)")) # Jul 6 14:04:01 pid:29440
            
              print(show_time_of_pid("Jul 6 14:05:01 computer.name CRON[29440]: USER (naughty_user)")) # Jul 6 14:05:01 pid:29440
            

            【讨论】:

              【解决方案7】:

              我建议看看Logstash 而不是发明自行车。它稳定、成熟、可扩展且可用于生产。

              【讨论】:

                【解决方案8】:

                findall() 方法的简单解决方案和另一种方法:

                import re
                def show_time_of_pid(line):
                  pattern = r"(\w+ \d+ \d+:\d+:\d+)+.*?\[(\d+)\]"
                  result = re.findall(pattern, line)
                  return "{} pid:{}".format(result[0][0], result[0][1])
                

                输出:

                Jul 6 14:01:23 pid:29440
                Jul 6 14:02:08 pid:29187
                Jul 6 14:02:09 pid:29187
                Jul 6 14:03:01 pid:29440
                Jul 6 14:03:40 pid:29807
                Jul 6 14:04:01 pid:29440
                Jul 6 14:05:01 pid:29440
                

                【讨论】:

                  【解决方案9】:

                  我对这个问题的解决方案:

                  import re
                  def show_time_of_pid(line):
                    pattern = r"(\w*\s\d\s\d.......).*\[(\d....)"
                    result = re.search(pattern, line)
                    return "{} pid:{}".format(result[1], result[2])
                  #Here is my output:
                  Jul 6 14:01:23 pid:29440
                  Jul 6 14:02:08 pid:29187
                  Jul 6 14:02:09 pid:29187
                  

                  【讨论】:

                    猜你喜欢
                    • 2019-02-26
                    • 2011-02-18
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-03-09
                    • 1970-01-01
                    • 2019-01-07
                    • 1970-01-01
                    相关资源
                    最近更新 更多