【问题标题】:Sort a CSV file by last name with PHP使用 PHP 按姓氏对 CSV 文件进行排序
【发布时间】:2009-08-13 14:54:45
【问题描述】:

如何使用 PHP 对以下 CSV 文件进行排序?我想按姓氏排序。我是否以某种方式使用正则表达式来获取姓氏的第一个字母?任何帮助表示赞赏

这是我的 CSV 文件的摘录 - 带有“;”名称和地址之间的分隔符

John C. Buckley, M.D.;123 Main Street, Bethesda MD 20816
Steven P. Wood;345 Elm Street, Rockville, MD 20808
Richard E. Barr-Fernandez;234 Pine Street, Takoma Park MD 20820
Charles Andrew Powell; 678 Oak Street, Gaithersburg MD 20800
Mark David Horowitz, III; 987 Wall Street, Silver Spring MD 20856

【问题讨论】:

  • WTF .. 它没有让我回答....
  • 不同 - 有些超过 2000
  • 那是带有真实姓名和地址的真实摘录吗?你真的不应该在互联网上发布其他人的详细信息......
  • 赌注——它们是假的。我同意你的看法。我不会发布真实的细节。
  • Thomas,我不认为你可以 100% 准确地提取姓氏,除非你愿意做很多工作。您可能必须决定什么对您来说“足够好”。见stackoverflow.com/questions/103422/…

标签: php arrays csv sorting


【解决方案1】:

这是我的尝试。不过,我不确定正则表达式在提取姓氏方面有多强大。

<?php
$handle = fopen('c:/csv.txt', 'r') or die('cannot read file');
$surnames = array();
$rows = array();

//build array of surnames, and array of rows
while (false != ( $row = fgetcsv($handle, 0, ';') )) {
    //extract surname from the first column
    //this should match the last word before the comma, if there is a comma
    preg_match('~([^\s]+)(?:,.*)?$~', $row[0], $m);
    $surnames[] = $m[1];
    $rows[] = $row;
}

fclose($handle);

//sort array of rows by surname using our array of surnames
array_multisort($surnames, $rows);

print_r($rows);
//you could write $rows back to a file here if you wanted.

编辑

我刚刚意识到您实际上并不需要去掉 people 的后缀,因为这可能不会真正影响排序。您可以在空间上拆分第一列并取最后一列(如 karim79 建议的那样)。如果这个人有更多带空格的后缀,这可能会中断,所以我会保持我的答案不变。

【讨论】:

  • +1 @Tom Haigh,我正在编写类似的代码,也许只是在空间''处拆分并获取结果数组的最后一个偏移量?如 $name = split(" ", $name);$lastName = $name[count($name) - 1];
  • 汤姆,这很好用。真正愚蠢的问题 - 我怎样才能简单地将行打印或回显到页面。谢谢!
  • print_r() 应该已经这样做了。如果需要,您可以打印到表格,这应该是使用 foreach 遍历数组并打印每个“子”数组的值的简单案例。
  • 太棒了。再次感谢。完美运行。
【解决方案2】:

嗯,因为它是 CSV

$lines = file($file);
foreach($lines as $line)
{
    $parts = explode(";", $line);
    $last = explode(" ", $parts[0]);
    $last = end($last);
    $array[$last] = $parts;
}

ksort($array);

// ..... write it back to file

【讨论】:

  • 我认为csv数据实际上是用分号分隔的,看起来像逗号是用来分割地址行的,也是用来添加名称后缀的
  • 这看起来很有希望。我将您第一次爆炸功能中的分隔符更改为分号。但是,当它选择分解名称的最后一部分时,数组仍然会感到困惑,因为有些名称以“MD”或“III”或“Jr”结尾。
  • 在示例中,M.D 在分号之后,但是,是的,不完全确定您将如何解决这个问题。我可以只使用第三个值,但如果有人有多个中间名或在他们的名字或中间名中有空格,它就会把它扔掉。
  • 这比看起来更难。见stackoverflow.com/questions/103422/…
  • 在 foreach 循环的第一行稍作调整:我用 $parts = str_getcsv($line, ',', '"') 替换了 $parts = explode(";", $line),因为我的 csv 引号中有逗号,我想忽略。见stackoverflow.com/a/5132572/4504073。
【解决方案3】:

PHP 函数array_multisort 应该做你想做的事。您需要将 CSV 读入一个多维数组 - 请参阅链接页面上的第三个示例。

【讨论】:

  • 求姓氏怎么样?
  • 我猜我错过了那部分,我的错。您已经接受了一个答案,但我的做法是将名称拆分为空格,取出最后一个元素并将其作为新元素添加到“行”中。然后按该字段排序。
猜你喜欢
  • 2020-11-03
  • 1970-01-01
  • 2015-07-08
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 2021-01-04
  • 2013-11-03
  • 2019-05-06
相关资源
最近更新 更多