【问题标题】:Get all possible lines that contains a particular pattern获取包含特定模式的所有可能行
【发布时间】:2017-09-09 04:41:56
【问题描述】:

我正在尝试使用正则表达式来获取包含特定单词“authenticate(no)”的所有行。我的代码段是:

$pattern = "/^.*\bauthenticate\b.*$/m";
$matches = array();
preg_match($pattern, $text, $matches);

var_dump($matches);

输出:

array(1) { [0]=> string(54) "client.address=10.50.131.0/24 验证(否)“ }

它给我带来了第一行符合条件的一行。如何修改它以获得所有可能的行?

文本示例如下:

ALLOW client.address=Wireless-Guest-Segment limit_bandwidth.client.inbound(Guest) limit_bandwidth.server.outbound(Guest) access_log[main](yes) 


client.address=10.50.131.0/24 authenticate(no) 

client.address=10.50.202.30 authenticate(no) 

client.address=10.50.202.18 authenticate(no) 

client.address=10.50.200.80 authenticate(no) 

client.address=10.50.202.31 authenticate(no) 

client.address=10.50.204.30 authenticate(no) 

client.address=10.50.204.164 authenticate(no) 

client.address=10.50.204.39 authenticate(no) 

client.address=10.50.204.123 authenticate(no) 

client.address=10.50.130.5 authenticate(no) 

authenticate(integrated_windows_authenticatio) authenticate.force(no) authenticate.mode(auto)

【问题讨论】:

    标签: php regex string preg-match


    【解决方案1】:

    使用preg_match_all 来获取所有可能的匹配项

    【讨论】:

      【解决方案2】:

      您不必使用正则表达式来选择包含文字字符串的行。 strpos 是执行此操作的函数。而不是将您的数据分成几行或制作一个描述整行的模式,而是逐行读取您的字符串或文件:

      $handle = fopen("data:text/plain,$text", 'r'); // or fopen('/path/to/your/file', r);
      
      $results = [];
      
      while ( false !== $line = stream_get_line($handle, 1024, "\n") ) { // or "\r\n"
          if ( false !== strpos($line, 'authenticate(no)') )
              $results[] = $line;
      }
      
      print_r($results);
      

      这种方式适用于字符串或文件。它是文件的优点是文件内容永远不会完全加载到内存中,因为它是作为流读取的。请注意,您可以以相同的方式(lazy evaluation)继续,而不是将结果存储在数组中,并将 while 循环放入仅在您需要时产生结果的生成器中,例如:

      $handle = fopen("data:text/plain,$text", 'r'); // or fopen('/path/to/your/file', r);
      
      function getLine($handle, $filter) {
          while ( false !== $line = stream_get_line($handle, 1024, "\n") ) {
              if ( false !== strpos($line, $filter) )
                   yield $line;
          }
      }
      
      foreach (getLine($handle, 'authenticate(no)') as $line) {
          echo $line, PHP_EOL;
      }
      

      但如果出于任何原因需要加载整个内容,您可以使用返回行数组的file 函数并使用array_filter 过滤这些行(或在简单的foreach 循环中找到它们):

      $results = array_filter(file('/path/to/your/file'), function ($i) {
          return strpos($i, 'authenticate(no)') !== false;
      });
      

      【讨论】:

        【解决方案3】:

        您可以拆分行(假设它们使用新行或返回)然后使用 preg_grep。

        $pattern = "/^.*\bauthenticate\b.*$/m";
        
        $matches = preg_grep($pattern, preg_split('/[\n\r]+/', $text));
        
        
        var_dump($matches);

        上面的代码将返回任何带有文本“authenticate”的行 下面的代码将只返回带有文本“authenticate(no)”的行。

        $pattern = "/authenticate\(no\)/";
        
        $matches = preg_grep($pattern, preg_split('/[\n\r]+/', $text));
        
        var_dump($matches);

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-08-03
          • 1970-01-01
          • 2016-09-28
          • 1970-01-01
          • 2023-01-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多