抓取整条线的PHP脚本

时间:2010-08-21 21:12:26

标签: php line fetch text-files

感谢您抽出宝贵时间阅读本文,我将感谢每一个回复,无论内容的质量如何。 :)

我正在尝试创建一个php脚本,用于在文本文件中搜索特定文本。一个人在HTML表单中键入特定文本,php脚本应该在文本文件中搜索该特定文本。

HTML表单的输入字段的值是“username”,在php文档中,变量“$ username”是输入的数据,示例如下所示:

$username = $_POST['username'];

下面的文本文件名为“begin.txt”:

  

“AULLAH1”“01/07/2010 15:28”“55621454”“123456”“123456.00”

     

“USERNAME”“7/3/2010 6:21 PM”“55621454”“123456”“123456.00”

     

“AULLAH1”“07/07/2010 15:05”“55621454”“189450”“123456.00”

     

“SUPREMEGAMER”“7/8/2010 6:42 PM”“55621454”“123456”“123456.00”

如果一个人输入HTML表单“AULLAH1”,我希望php脚本能够获取文本文件中的最后一个“AULLAH1”条目(例如,它应该抓住第三行而不是第一行,作为第三行line是包含文本“AULLAH1”的最后一个条目。此外,当一个人键入特定文本时,它不应该只是抓取文档或文本,它应该抓住整行:“AULLAH1”“07/07/2010 15:05”“55621454”“189450 “”123456.00“并将其放入php变量,可能是”$ grabbed“之类的东西?如果可能的话。

感谢所有的帮助,我期待着您的回复;谢谢。 :)如果我没有清楚地解释任何内容和/或您希望我更详细地解释,请回复。 :)

谢谢。

5 个答案:

答案 0 :(得分:3)

我不会使用文本文件存储凭据,但如果您必须至少将文本文件的格式更改为CSV布局

有这样的

AULLAH1,01/07/2010 15:28,55621454,123456,123456.00
USERNAME,7/3/2010 6:21 PM,55621454,123456,123456.00
AULLAH1" "07/07/2010 15:05 " "55621454" "189450" "123456.00
SUPREMEGAMER,7/8/2010 6:42 PM,55621454,123456,123456.00

在PHP中读取文件行我的行

<?php
$lines = file('begin.txt');
foreach($lines as $line)
{
     if(preg_match('/(?<username>.*?),(?<ts>.*?),(?<id_1>.*?),(?<id_2>.*?),(?<balance>.*?)/',$line,$parts))
     {
         if($_POST['username'] == $parts['username'])
         {
             //Do what you need here.
             break;
         }
     }
}
?>

你也可以使用explode witch更快,但仅限于自动生成数组键!

<?php
$lines = file('begin.txt');
foreach($lines as $line)
{
    $parts = explode(',',$line);
     if($_POST['username'] == $parts[0])
     {
         //Do what you need here.
         break;
     }
}
?>

答案 1 :(得分:2)

您可以使用SplFileObject并逐行迭代文件。

请注意,迭代文件比使用file()file_get_contents()更有效,因为它不会将整个文件内容读入数组或变量。

$username = 'AULLAH1';
$file = new SplFileObject("data.csv");
$grabbed = FALSE;
while (!$file->eof()) {
     $data = $file->fgetcsv(' ');
     if($data[0] === $username) {
         $grabbed = $file->current();
     }
}
echo $grabbed;

因为fgetcsv()在解析行时考虑了分隔符,附件和转义字符,所以它并不是很快。如果你必须以这种方式解析几百或几千行,请确保你确实需要它。


另一种方法是检查当前行是否包含某处的用户名字符串。在您在问题中显示的文件格式中,这是可行的,因为其余字段包含数字,因此不会出现任何误报:

$username = 'AULLAH1';
$file = new SplFileObject("data.txt");
$grabbed = FALSE;
foreach($file as $line) {
    if(strpos($line, $username) !== FALSE) {
        $grabbed = $line;
    }
}
echo $grabbed;

如果您想确保在第1位找到$ username,请更改if条件以测试=== 1


如果由于某种原因,您希望拥有用户名出现的所有行,您可以编写自定义FilterIterator来迭代文件内容,例如

class UsernameFilter extends FilterIterator
{
    protected $_username;
    public function __construct(Iterator $iterator, $username)
    {
        $this->_username = $username;
        parent::__construct($iterator);
    }
    public function accept()
    {
        return strpos($this->current(), $this->_username) !== FALSE;
    }
}

然后你可以简单地使用foreach。 FilterIterator会将每一行传递给accept(),并且实际上只使用它返回TRUE的那些行。

$filteredLines = new UsernameFilter(new SplFileObject('data.txt'), 'AULLAH1');
foreach($filteredLines as $line) {
    echo $line;
}

上面会输出

"AULLAH1" "01/07/2010 15:28 " "55621454" "123456" "123456.00"
"AULLAH1" "07/07/2010 15:05 " "55621454" "189450" "123456.00"

如果你想在数组中使用这些行,你可以

$lines = iterator_to_array($filteredLines);

并查看最后一项

echo end($lines);

答案 2 :(得分:2)

使用preg_match_all()可能是一个解决方案:

$file = file_get_contents($filename);
$username = 'ALLUAH1';
preg_match_all('/^"'.preg_quote($username, '/').'".*$/m', $file, $matches);
  // Note that the '/m' flag of the regex makes '^' and '$' match
  // the beginning and end of each line.
  // Also note that I am using preg_quote() to escape special regex characters

$grabbed = array_pop($matches[0]);

现在$grabbed应该保留该用户最后一行的值。

相关链接:

答案 3 :(得分:2)

这是我能想到的最简单的实现方法。此方法只是以相反的顺序遍历文件的行,因此不需要搜索每一行。它还假设用双引号括起来的用户名是输入文件每行的第一件事。

$username = "AULLAH1";
$input_file = file("begin.txt");

$grabbed = "";

for($i = count($input_file) - 1; $i >= 0; $i--)
{
  // Note: Exactly zero (string starts the line), NOT "FALSE"
  if(strpos($input_file[$i], "\"$username\"") === 0)
  {
    $grabbed = $input_file[$i];
    break;
  }
}

答案 4 :(得分:2)

这是我能想到的最短时间:

$list = file_get_contents('data.txt');
echo strstr(substr($list, strrpos($list, 'AULLAH1')-1), PHP_EOL, TRUE);

这会将文件读入内存。然后它找到字符串'AULLAH1'的最后一次出现的偏移量。在此出现之前一直到下一个换行符的所有内容都将被返回。

由于strstr()的第三个参数,这需要PHP5.3,并且需要比上面的iterator solution更多的内存。根据您的换行符,您可能必须将PHP_EOL更改为文件中使用的换行符。