0

好的,所以我有一个包含学生编号和相应姓名的文本文件。我想获取所有这些数据,正确格式化它们(大写,适当数量的空格等)并将它们放在另一个文件中。原文格式有点像这样:

20111101613 XXXXXXXX  , XXXX
20111121235 xxXXXX, xxxxxx
20111134234   XXXX, XxxX
20111104142 XXXXXxxxX, XXXX
20111131231 XX , XXXXXX

示例:输入文件内容是这样的:

20111112346 Zoomba, Samthing
20111122953 Acosta, Arbyn
20110111241 Smith, John
20111412445 Over, Flow Stack
20111112345 foo, BAR

并且输出文件内容应该是这样的:

20111122953 ACOSTA, ARBYN
20111112345 FOO, BAR
20111412445 OVER, FLOW STACK
20110111241 SMITH, JOHN
20111112346 ZOOMBA, SAMTHING

编辑:有人可以给我一个提示或解决方案如何使用正则表达式制作这个函数吗?

function sortslist($infile, $outfile)
{
    // open the input file named conversion.txt
    $inptr = fopen($infile, "r");
    if (!$inptr)
    {
        trigger_error("File cannot be opened: $infile", E_USER_ERROR);
    }

    // initialize student number to zero
    $snum = 0;

    // number of letters in the name string
    $n = 0;

    // initialize the name string to be empty
    $name = "";

    // iteratively scan the input file
    $done = false;
    while (!$done)
    {
        // get each character in the file
        $c = fgetc($inptr);

        // if the character is a digit, add it to the student number
        if (ctype_digit($c))
        {
            $snum = (($snum * 10) + ($c - '0'));
        }

        // else, add to name string including commas and space. Input file might have tabs
        else if (ctype_alpha($c) || ($n > 0 && ($c == " " || $c == "\t")) || $c == ",")
        {
            // append the new character to name string
            $name .= $c;

            // add a space after the comma
            if ($c == ",")
            {
                $name .= " ";
                $n++;
            }

            // increment the number of letters
            $n++;
        }

        // end of the line
        else if ($c == "\n" || !$c)
        {
            // 0 is added to student numbers when newline is detected so neglect them
            if ($snum != 0 && $name != "\n")
            {
                // replace consecutive spaces with one space only
                $name = preg_replace(['/\s\s+/', '/\s,/', '/(\s*)(?>$)/'], [' ', ',', ''], $name);

                // record student number and name
                $info['snum'][] = $snum;
                $info['name'][] = strtoupper($name);
            }

            // reset the values needed
            $snum = 0;
            $n = 0;
            $name = "";

            // if we hit the end of the file then it is done
            if (!$c)
            {
                $done = true;
            }
        }
    }

    // sort the students names alphabetically
    array_multisort($info['name'], $info['snum']);

    // combine the name strings and there corresponding student number
    $i = 0;
    $students = [];
    $last_student = end($info['snum']);
    foreach ($info['snum'] as $snum)
    {
        $students[$snum] = $snum . " " . $info['name'][$i++];

        // update input file too
        fwrite($inptr, $students[$snum]);

        // don't add a newline to the end of the file
        if ($snum != $last_student)
        {
            $students[$snum] .= "\n";
        }
    }

    // put it into a new file called slist.txt
    file_put_contents($outfile, $students, LOCK_EX);

    // close the input file
    fclose($inptr);
}
4

1 回答 1

0

您的问题在于$hashtable字符串中的值首先与学生 ID 一起存储。asort()将始终查看值的开头,并根据该值进行排序。因此,为了按姓名排序,您必须将学生 ID 和姓名分成两个单独的数组,然后使用array_multisort().

代替:

$hashtable[$snum] = $snum . " " . strtoupper($name) . "\n";

和:

$snums[] = $snum;
$names[] = strtoupper($name);

array_multisort($names, $snums);

$j = 0;
while ($names) {
    $hashtable[$snum] = $snums[$j]. " ". $names[$j]. "\n";
    $j++;
}
于 2013-04-14T16:17:12.260 回答