使用数字和字母向文件打印已排序的字符串,以查找preg_match解决方案

Ok, so I have a text file filled with student numbers and the corresponding name. I want to get all those data, format them properly (uppercase, proper number of spaces, etc.) and put them in another file. The original text format is somewhat like this:

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

Example: Input file content is something like this:

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

And the output file content should be like this:

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

EDIT: Can someone give me a hint or the solution on how to make this function with using regular expressions?

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 == "
" || !$c)
        {
            // 0 is added to student numbers when newline is detected so neglect them
            if ($snum != 0 && $name != "
")
            {
                // 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] .= "
";
        }
    }

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

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

Your problem lies in the fact that $hashtable values are stored with the student ID first in the string. asort() will allways look at the beginning of the value, and sort according to that. So in order to sort by the name, you will have to split up the student ID and the name into two separate arrays and then sort them using array_multisort().

Replace:

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

with:

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

array_multisort($names, $snums);

$j = 0;
while ($names) {
    $hashtable[$snum] = $snums[$j]. " ". $names[$j]. "
";
    $j++;
}