【问题标题】:PHP - Find a string in file then show it's line numberPHP - 在文件中查找一个字符串,然后显示它的行号
【发布时间】:2013-11-04 01:57:04
【问题描述】:

我有一个应用程序需要打开文件,然后在其中找到字符串,并打印找到字符串的行号。

例如,文件 example.txt 包含少量哈希:

APLF2J51 1a79a4d60de6718e8e5b326e338ae533
EEQJE2YX 66b375b08fc869632935c9e6a9c7f8da O87IGF8R
c458fb5edb84c54f4dc42804622aa0c5 APLF2J51
B7TSW1ZE 1e9eea56686511e9052e6578b56ae018
EEQJE2YX affb23b07576b88d1e9fea50719fb3b7


所以,我想用 PHP 搜索“1e9eea56686511e9052e6578b56ae018”并打印出它的行号,在本例中为 4。

请注意,文件中不会有多个哈希值。

我在互联网上找到了一些代码,但似乎都没有。

我试过这个:

<?PHP
$string = "1e9eea56686511e9052e6578b56ae018"; 
$data   = file_get_contents("example.txt"); 
$data   = explode("\n", $data); 
for ($line = 0; $line < count($data); $line++) { 
if (strpos($data[$line], $string) >= 0) { 
die("String $string found at line number: $line"); 
} 
} 
?>

它只是说在第 0 行找到了字符串......这是不正确的......

最终申请比这复杂得多... 找到行号后,它应该替换其他字符串,并将更改保存到文件中,然后进行进一步处理....

提前致谢:)

【问题讨论】:

  • 你可能的尝试?
  • 我刚刚添加了我的最后一次尝试。谢谢你提醒我。
  • 您自己的尝试不起作用的原因是因为 strpos 在找不到针时返回 false,这将使您的 if 语句评估为 true。您必须写 !== false 才能使这样的声明生效。
  • @Daniel Perván - 我刚试过,是的,现在可以了。谢谢!

标签: php string numbers find line


【解决方案1】:

一个超基本的解决方案可能是:

$search      = "1e9eea56686511e9052e6578b56ae018";
$lines       = file('example.txt');
$line_number = false;

while (list($key, $line) = each($lines) and !$line_number) {
   $line_number = (strpos($line, $search) !== FALSE) ? $key + 1 : $line_number;
}

echo $line_number;

节省内存的版本,用于较大的文件:

$search      = "1e9eea56686511e9052e6578b56ae018";
$line_number = false;

if ($handle = fopen("example.txt", "r")) {
   $count = 0;
   while (($line = fgets($handle, 4096)) !== FALSE and !$line_number) {
      $count++;
      $line_number = (strpos($line, $search) !== FALSE) ? $count : $line_number;
   }
   fclose($handle);
}

echo $line_number;

【讨论】:

  • 它不起作用。它什么也不输出......是的,我试过 echo $line_number;无论如何,谢谢。
  • 现在它就像魅力一样。选择你的答案是最好的,因为我喜欢使用 file() 而不是 file_get_contents();编辑:内存保护版本不起作用。输出为空白。
  • 现在我尝试了内存保护版本,它也可以完美运行。谢谢!
【解决方案2】:
function get_line_from_hashes($file, $find){
    $file_content = file_get_contents($file);
    $lines = explode("\n", $file_content);

    foreach($lines as $num => $line){
        $pos = strpos($line, $find);
        if($pos !== false)
            return $num + 1
    }
    return false
}

get_line_from_hashes("arquivo.txt", "asdsadas2e3xe3ceQ@E"); //return some number or false case not found.

【讨论】:

  • 您忘记添加了;在 return-s 上,所以它会引发错误。返回 $num + 1;返回假;改正后效果很好。谢谢!
  • 警告:如果文件很大,如果使用file_get_contents()explode(),内存消耗会很高。
  • 是的,我知道。但目前它将用于最大 500kb 的文件。我不确定如何降低内存消耗......
  • 而不是return $num + 1;,它必须是return $num;,否则它会在之后得到一行
【解决方案3】:

如果您需要快速且通用的解决方案,也可以在文件中查找多行文本的行号,请使用:

$file_content = file_get_contents('example.txt');

$content_before_string = strstr($file_content, $string, true);

if (false !== $content_before_string) {
    $line = count(explode(PHP_EOL, $content_before_string));
    die("String $string found at line number: $line");
}

仅供参考 仅适用于 PHP 5.3.0+。

【讨论】:

    【解决方案4】:
    $pattern = '/1e9eea56686511e9052e6578b56ae018/';
    if (preg_match($pattern, $content, $matches, PREG_OFFSET_CAPTURE)) {
        //PREG_OFFSET_CAPTURE will add offset of the found string to the array of matches
        //now get a substring of the offset length and explode it by \n
        $lineNumber = count(explode("\n", substr($content, 0, $matches[0][1])));
    }
    

    【讨论】:

      【解决方案5】:

      如果文件不是非常大,那么只需将文件读入数组file,搜索单词preg_grep,获取该行的索引key并添加1,因为数组从@开始987654325@:

      $string = "1e9eea56686511e9052e6578b56ae018"; 
      echo key(preg_grep("/$string/", file("example.txt"))) + 1;
      

      【讨论】:

        【解决方案6】:

        我发现这很好用而且效率很高;只需按每一行分解文件并在数组中搜索您的搜索词,如下所示:

            function getLineNum($haystack, $needle){
        
                # Our Count
                $c = 1;
        
                # Turn our file contents/haystack into an array
                $hsarr = explode("\n", $haystack);
                
                # Iterate through each value in the array as $str
                foreach($hsarr as $str){
        
                    # If the current line contains our needle/hash we are looking for it
                    # returns the current count.
                    if(strstr($str, $needle)) return $c;
        
                    # If not, Keep adding one for every new line.
                    $c++;
                }
        
                # If nothing is found
                if($c >= count($hsarr)) return 'No hash found!';
            }
        

        编辑:查看其他答案,我意识到 Guilherme Soares 有类似的方法,但使用了 strpos,在这种情况下不起作用。所以我在这里根据他的想法做了一些改动:

            function getLineNum($haystack, $needle){
                $hsarr = explode(PHP_EOL, $haystack);
                foreach($hsarr as $num => $str) if(strstr($str, $needle)) return $num + 1;
                return 'No hash found!';
            }
        

        现场演示:https://ideone.com/J4ftV3

        【讨论】:

          猜你喜欢
          • 2020-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多