Php 从字符串中提取用户名和消息?

Php 从字符串中提取用户名和消息?,php,regex,Php,Regex,因此,我试图从日志文件中提取特定数据,如日期、用户名和消息本身 这是一个模拟文件的外观: [2017-03-14 11:48:22] Steve T: Hi! [2017-03-14 11:49:01] Oscar: Hi! :D How are u doin? [2017-03-14 11:50:24] Steve T: Im doing great :P 我可以使用preg_match(“/(\d{4})-(\d{2})(\d{2}):(\d{2}):(\d{2}):(\d{2})/”,$

因此,我试图从日志文件中提取特定数据,如日期、用户名和消息本身

这是一个模拟文件的外观:

[2017-03-14 11:48:22] Steve T: Hi!
[2017-03-14 11:49:01] Oscar: Hi! :D How are u doin?
[2017-03-14 11:50:24] Steve T: Im doing great :P

我可以使用
preg_match(“/(\d{4})-(\d{2})(\d{2}):(\d{2}):(\d{2}):(\d{2})/”,$string,$matches)
,提取日期,但是如何使用正则表达式获取用户名和消息?

这里有一个工作正则表达式:

/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] ([\w\s]+): (.+)$/gm
您可以在这里看到一个演示:

它的意思是:

  • ^
    -行首
  • \[(\d{4}-\d{2}-\d{2}\d{2}:\d{2}:\d{2})\]
    -方括号内的日期(必须转义)
  • ([\w\s]+)
    -用户名(由单词(
    \w
    )和空格(
    \s
    )字符混合而成
    • 如果用户名可以包含除冒号以外的任何字符,则还可以使用:
      ([^::]+)
  • -用户名后的冒号(匹配项被丢弃)
  • (.+)
    -匹配所有其他内容
  • $
    -行末
下面是一个PHP演示:

注意事项:

  • 注意用户名格式,现在我假设它只包含单词和空格字符
  • 如果消息可以包含行,则需要调整正则表达式

    • 这是一个有效的正则表达式:

      /^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] ([\w\s]+): (.+)$/gm
      
      您可以在这里看到一个演示:

      它的意思是:

      • ^
        -行首
      • \[(\d{4}-\d{2}-\d{2}\d{2}:\d{2}:\d{2})\]
        -方括号内的日期(必须转义)
      • ([\w\s]+)
        -用户名(由单词(
        \w
        )和空格(
        \s
        )字符混合而成
        • 如果用户名可以包含除冒号以外的任何字符,则还可以使用:
          ([^::]+)
      • -用户名后的冒号(匹配项被丢弃)
      • (.+)
        -匹配所有其他内容
      • $
        -行末
      下面是一个PHP演示:

      注意事项:

      • 注意用户名格式,现在我假设它只包含单词和空格字符
      • 如果消息可以包含行,则需要调整正则表达式

        • 使用格式化字符串的替代方法

          $str = <<<'EOD'
          [2017-03-14 11:48:22] Steve T: Hi!
          [2017-03-14 11:49:01] Oscar: Hi! :D How are u doin?
          [2017-03-14 11:50:24] Steve T: Im doing great :P
          EOD;
          
          $handle = fopen("data://text/plain,$str", 'r');
          while ( false !== $line = fgets($handle) ) {
              print_r(sscanf($line, "[%[^]]] %[^:]: %[^\1]"));
          }
          

          $str=使用格式化字符串的替代方法

          $str = <<<'EOD'
          [2017-03-14 11:48:22] Steve T: Hi!
          [2017-03-14 11:49:01] Oscar: Hi! :D How are u doin?
          [2017-03-14 11:50:24] Steve T: Im doing great :P
          EOD;
          
          $handle = fopen("data://text/plain,$str", 'r');
          while ( false !== $line = fgets($handle) ) {
              print_r(sscanf($line, "[%[^]]] %[^:]: %[^\1]"));
          }
          

          $str=您可以找到第一个
          的位置,但如果您的用户的姓名带有
          ,则此方法无效。您可以找到第一个
          的位置,但如果您的用户的姓名带有
          ,则此方法无效。是的,这是最好的选择。请注意,这将无法很好地处理包含非单词或空格字符的用户名,例如
          Michael O'Hare
          oscar the grouch
          @salathe true,但他从未提及用户名格式。不过,我会在回答中强调这一点。是的,这是最好的选择。请注意,对于包含非单词或空格字符的用户名,例如
          Michael O'Hare
          oscar the grouch
          @Sala,这将无法很好地处理,但他从未提及用户名格式。不过,我会在回答中强调这一点。