diff --git a/web/reinfo.php b/web/reinfo.php index 58ae83e..a7da4e4 100644 --- a/web/reinfo.php +++ b/web/reinfo.php @@ -117,37 +117,85 @@ function parse_diff_blocks($text) { $chunk = trim($chunk); if ($chunk === '') continue; - // full mode: 形如 "========[test1.out]=========" 开头 - if (preg_match('/^=+\[([^\]]+)\]=+$/m', $chunk, $m_head)) { - $name = $m_head[1]; - // 提取 "------diff out 200 lines-----" 后面的内容 - if (preg_match('/------diff out[^\n]*-+\n(.*?)\n=+\s*$/s', $chunk, $m_diff)) { - $diff_text = trim($m_diff[1]); - } else { - continue; + // 格式 1: 整段就是一个 =====[name]===== 块(包含表头+数据+结尾 ====) + // 形如 "========[test1.out]========\nExpected | Yours\nFail | Fall\n==============================" + if (preg_match('/^=+\[([^\]]+)\]\=+(.+?)\n=+\s*$/s', $chunk, $m)) { + $name = trim($m[1]); + $body = $m[2]; + // body 形如 "\nExpected | Yours\nFail | Fall" + // 去掉首尾的换行符 + $body = trim($body, "\n\r"); + $lines_in_body = explode("\n", $body); + $expected = array(); + $yours = array(); + $found_header = false; + foreach ($lines_in_body as $bl) { + $bl = rtrim($bl); + if ($bl === '') continue; + // 跳过表头 + if (!$found_header && preg_match('/^Expected.*\|.*Yours/i', $bl)) { + $found_header = true; + continue; + } + if (!$found_header && (preg_match('/^\|?--\s*\|/', $bl) || trim($bl) === '--')) { + continue; + } + $parsed = parse_one_diff_line($bl); + if ($parsed !== null) { + $expected[] = $parsed[0]; + $yours[] = $parsed[1]; + $found_header = true; + } else { + $expected[] = $bl; + $yours[] = ''; + $found_header = true; + } } - $lines = parse_diff_side_by_side($diff_text); - if (!empty($lines)) { + if (!empty($expected)) { $blocks[] = array( 'name' => $name, - 'expected' => $lines['expected'], - 'yours' => $lines['yours'], + 'expected' => $expected, + 'yours' => $yours, 'full_mode' => true, ); } continue; } - // simple mode: 形如 "test1.out\n--\n|Expected|Yours\n|--|--\n|..." - if (preg_match('/^([^\n|]+)\n--\n\|Expected\|Yours\n\|--\|--\n(.*)$/s', $chunk, $m)) { + // 格式 2: simple mode "test1.out\n--\n|Expected|Yours\n|--|--\n|row1|row2" + if (preg_match('/^([^\n=|]+)\n--\n([\s\S]+)$/', $chunk, $m)) { $name = trim($m[1]); - $table = $m[2]; - $lines = parse_pipe_diff_table($table); - if (!empty($lines)) { + $body = $m[2]; + $lines_in_body = explode("\n", $body); + $expected = array(); + $yours = array(); + $found_header = false; + foreach ($lines_in_body as $bl) { + $bl = rtrim($bl); + if ($bl === '') continue; + if (!$found_header && preg_match('/Expected.*\|.*Yours/i', $bl)) { + $found_header = true; + continue; + } + if (!$found_header && (preg_match('/^\|?--\s*\|/', $bl) || trim($bl) === '--')) { + continue; + } + $parsed = parse_one_diff_line($bl); + if ($parsed !== null) { + $expected[] = $parsed[0]; + $yours[] = $parsed[1]; + $found_header = true; + } else { + $expected[] = $bl; + $yours[] = ''; + $found_header = true; + } + } + if (!empty($expected)) { $blocks[] = array( 'name' => $name, - 'expected' => $lines['expected'], - 'yours' => $lines['yours'], + 'expected' => $expected, + 'yours' => $yours, 'full_mode' => false, ); } @@ -157,47 +205,40 @@ function parse_diff_blocks($text) { } /** - * 解析 "|expected|yours\n" 格式的表格 + * 解析单行 "expected | yours" 格式 + * 支持 "|a|b"、"a | b"、"a|b" 等 + * 返回 [left, right] 或 null(无法解析) */ -function parse_pipe_diff_table($text) { - $expected = array(); - $yours = array(); - $lines = explode("\n", $text); - foreach ($lines as $line) { - if (strlen($line) < 2 || $line[0] !== '|') continue; +function parse_one_diff_line($line) { + $line = rtrim($line); + if ($line === '') return null; + + // 格式 A: "|a|b" (首尾带 |) + if ($line[0] === '|') { $rest = substr($line, 1); $pos = strpos($rest, '|'); - if ($pos === false) continue; - $left = substr($rest, 0, $pos); - $right = substr($rest, $pos + 1); - $expected[] = $left; - $yours[] = $right; - } - if (empty($expected)) return array(); - return array('expected' => $expected, 'yours' => $yours); -} - -/** - * 解析 `diff -y` 格式: " < expected > yours" 或 " expected | yours" - */ -function parse_diff_side_by_side($text) { - $expected = array(); - $yours = array(); - $lines = explode("\n", $text); - foreach ($lines as $line) { - if (preg_match('/^(.*?)\s+[<>|]\s+(.*)$/', $line, $m)) { - $expected[] = $m[1]; - $yours[] = $m[2]; - } elseif (trim($line) === '') { - // 空行:两边都空 - } else { - // 单边(一边空):整行属于另一边 - $expected[] = $line; - $yours[] = ''; + if ($pos !== false) { + return array(substr($rest, 0, $pos), substr($rest, $pos + 1)); } } - if (empty($expected)) return array(); - return array('expected' => $expected, 'yours' => $yours); + + // 格式 B: "a | b" 或 "a | b"(带空格的 markdown 风格) + // 注意:可能行内有空格,所以用 " | " 或 " | " 等宽松匹配 + if (preg_match('/^(.*?)\s+\|\s+(.*)$/', $line, $m)) { + // 确保左右两边都非空 + $left = trim($m[1]); + $right = trim($m[2]); + if ($left !== '' || $right !== '') { + return array($left, $right); + } + } + + // 格式 C: "ab"(diff -y 风格) + if (preg_match('/^(.*?)\s+([<>])\s+(.*)$/', $line, $m)) { + return array($m[1], $m[3]); + } + + return null; } $view_reinfo = ""; @@ -218,7 +259,9 @@ if($ok){ $rt = pdo_query($sql,$id); $raw_error = ""; if(isset($rt[0])){ - $raw_error = str_replace("\n\r","\n",$rt[0]['error']); + $raw_error = $rt[0]['error']; + // 统一换行符:先替换 \r\n,再替换单独的 \r + $raw_error = str_replace(array("\r\n", "\r"), "\n", $raw_error); } // === 阶段 1:基于 solution.result 给"主解释"(永远非空)===