NissayaParser.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?php
  2. namespace App\Services;
  3. class NissayaParser
  4. {
  5. /**
  6. * 解析nissaya巴利文-缅文文本
  7. */
  8. public function parse(string $content): array
  9. {
  10. $lines = explode("\n", $content);
  11. $records = [];
  12. $currentRecord = null;
  13. $pendingNotes = [];
  14. $inCodeBlock = false;
  15. $codeBlockContent = '';
  16. $codeBlockDelimiter = '';
  17. for ($i = 0; $i < count($lines); $i++) {
  18. $line = $lines[$i];
  19. $trimmedLine = trim($line);
  20. // 检测代码块开始/结束 (支持 ``` 和 ``)
  21. if (preg_match('/^(```|``)$/', $trimmedLine, $matches)) {
  22. if (! $inCodeBlock) {
  23. // 开始代码块
  24. $inCodeBlock = true;
  25. $codeBlockDelimiter = $matches[1];
  26. $codeBlockContent = '';
  27. } elseif ($matches[1] === $codeBlockDelimiter) {
  28. // 结束代码块
  29. $inCodeBlock = false;
  30. $pendingNotes[] = trim($codeBlockContent);
  31. $codeBlockContent = '';
  32. $codeBlockDelimiter = '';
  33. }
  34. continue;
  35. }
  36. // 在代码块内
  37. if ($inCodeBlock) {
  38. $codeBlockContent .= $line."\n";
  39. continue;
  40. }
  41. // 空行跳过
  42. if (empty($trimmedLine)) {
  43. continue;
  44. }
  45. // 检查是否包含等号
  46. if (strpos($line, '=') !== false) {
  47. // 检查是否是以等号开头(补充上一条记录的翻译)
  48. if (strpos(ltrim($line), '=') === 0) {
  49. // 这是对上一条记录的翻译补充
  50. if ($currentRecord !== null && empty($currentRecord['translation'])) {
  51. $currentRecord['translation'] = trim(substr(ltrim($line), 1));
  52. }
  53. } else {
  54. // 保存之前的记录
  55. if ($currentRecord !== null) {
  56. $currentRecord['notes'] = $pendingNotes;
  57. $records[] = $currentRecord;
  58. $pendingNotes = [];
  59. }
  60. // 解析新记录
  61. [$original, $translation] = explode('=', $line, 2);
  62. $currentRecord = [
  63. 'original' => trim($original),
  64. 'translation' => trim($translation),
  65. 'notes' => [],
  66. ];
  67. }
  68. } else {
  69. // 没有等号的行
  70. if ($currentRecord !== null && empty($currentRecord['translation'])) {
  71. // 情况1: 上一行只有巴利文(等号后为空),当前行是缅文翻译
  72. $currentRecord['translation'] = trim($line);
  73. } elseif ($currentRecord === null) {
  74. // 情况2: 第一行没有等号,可能是不完整的巴利文
  75. $currentRecord = [
  76. 'original' => trim($line),
  77. 'translation' => '',
  78. 'notes' => [],
  79. ];
  80. } else {
  81. // 其他情况视为注释内容
  82. $pendingNotes[] = trim($line);
  83. }
  84. }
  85. }
  86. // 保存最后一条记录
  87. if ($currentRecord !== null) {
  88. $currentRecord['notes'] = $pendingNotes;
  89. $records[] = $currentRecord;
  90. }
  91. return $records;
  92. }
  93. /**
  94. * 解析文件
  95. */
  96. public function parseFile(string $filePath): array
  97. {
  98. if (! file_exists($filePath)) {
  99. throw new \InvalidArgumentException("文件不存在: {$filePath}");
  100. }
  101. $content = file_get_contents($filePath);
  102. return $this->parse($content);
  103. }
  104. }