NissayaParser.php 4.0 KB

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