RomanizeService.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. <?php
  2. namespace App\Services;
  3. /**
  4. * 控制器中
  5. public function convert(PaliTransliterationService $pali)
  6. {
  7. $result = $pali->myanmarToRoman('သမ္မာ');
  8. }
  9. // 或者使用 app() 助手函数
  10. $pali = app(PaliTransliterationService::class);
  11. $result = $pali->thaiToRoman('สมฺมา');
  12. */
  13. class RomanizeService
  14. {
  15. /**
  16. * 缅文字母映射表
  17. */
  18. private const MYANMAR_CHARS = [
  19. 'ႁႏၵ',
  20. 'ခ္',
  21. 'ဃ္',
  22. 'ဆ္',
  23. 'ဈ္',
  24. 'ည္',
  25. 'ဌ္',
  26. 'ဎ္',
  27. 'ထ္',
  28. 'ဓ္',
  29. 'ဖ္',
  30. 'ဘ္',
  31. 'က္',
  32. 'ဂ္',
  33. 'စ္',
  34. 'ဇ္',
  35. 'ဉ္',
  36. 'ဠ္',
  37. 'ဋ္',
  38. 'ဍ္',
  39. 'ဏ္',
  40. 'တ္',
  41. 'ဒ္',
  42. 'န္',
  43. 'ဟ္',
  44. 'ပ္',
  45. 'ဗ္',
  46. 'မ္',
  47. 'ယ္',
  48. 'ရ္',
  49. 'လ္',
  50. 'ဝ္',
  51. 'သ္',
  52. 'င္',
  53. 'င်္',
  54. 'ဿ',
  55. 'ခ',
  56. 'ဃ',
  57. 'ဆ',
  58. 'ဈ',
  59. 'စျ',
  60. 'ည',
  61. 'ဌ',
  62. 'ဎ',
  63. 'ထ',
  64. 'ဓ',
  65. 'ဖ',
  66. 'ဘ',
  67. 'က',
  68. 'ဂ',
  69. 'စ',
  70. 'ဇ',
  71. 'ဉ',
  72. 'ဠ',
  73. 'ဋ',
  74. 'ဍ',
  75. 'ဏ',
  76. 'တ',
  77. 'ဒ',
  78. 'န',
  79. 'ဟ',
  80. 'ပ',
  81. 'ဗ',
  82. 'မ',
  83. 'ယ',
  84. 'ရ',
  85. '႐',
  86. 'လ',
  87. 'ဝ',
  88. 'သ',
  89. 'aျ္',
  90. 'aွ္',
  91. 'aြ္',
  92. 'aြ',
  93. 'ၱ',
  94. 'ၳ',
  95. 'ၵ',
  96. 'ၶ',
  97. 'ၬ',
  98. 'ၭ',
  99. 'ၠ',
  100. 'ၡ',
  101. 'ၢ',
  102. 'ၣ',
  103. 'ၸ',
  104. 'ၹ',
  105. 'ၺ',
  106. '႓',
  107. 'ၥ',
  108. 'ၧ',
  109. 'ၨ',
  110. 'ၩ',
  111. '်',
  112. 'ျ',
  113. 'ႅ',
  114. 'ၼ',
  115. 'ွ',
  116. 'ႇ',
  117. 'ႆ',
  118. 'ၷ',
  119. 'ၲ',
  120. '႒',
  121. '႗',
  122. 'ၯ',
  123. 'ၮ',
  124. '႑',
  125. 'kaၤ',
  126. 'gaၤ',
  127. 'khaၤ',
  128. 'ghaၤ',
  129. 'aှ',
  130. 'aိံ',
  131. 'aုံ',
  132. 'aော',
  133. 'aေါ',
  134. 'aအံ',
  135. 'aဣံ',
  136. 'aဥံ',
  137. 'aံ',
  138. 'aာ',
  139. 'aါ',
  140. 'aိ',
  141. 'aီ',
  142. 'aု',
  143. 'aဳ',
  144. 'aူ',
  145. 'aေ',
  146. 'အါ',
  147. 'အာ',
  148. 'အ',
  149. 'ဣ',
  150. 'ဤ',
  151. 'ဥ',
  152. 'ဦ',
  153. 'ဧ',
  154. 'ဩ',
  155. 'ႏ',
  156. 'ၪ',
  157. 'a္',
  158. '္',
  159. 'aံ',
  160. 'ေss',
  161. 'ေkh',
  162. 'ေgh',
  163. 'ေch',
  164. 'ေjh',
  165. 'ေññ',
  166. 'ေṭh',
  167. 'ေḍh',
  168. 'ေth',
  169. 'ေdh',
  170. 'ေph',
  171. 'ေbh',
  172. 'ေk',
  173. 'ေg',
  174. 'ေc',
  175. 'ေj',
  176. 'ေñ',
  177. 'ေḷ',
  178. 'ေṭ',
  179. 'ေḍ',
  180. 'ေṇ',
  181. 'ေt',
  182. 'ေd',
  183. 'ေn',
  184. 'ေh',
  185. 'ေp',
  186. 'ေb',
  187. 'ေm',
  188. 'ေy',
  189. 'ေr',
  190. 'ေl',
  191. 'ေv',
  192. 'ေs',
  193. 'ေy',
  194. 'ေv',
  195. 'ေr',
  196. 'ea',
  197. 'eā',
  198. '၁',
  199. '၂',
  200. '၃',
  201. '၄',
  202. '၅',
  203. '၆',
  204. '၇',
  205. '၈',
  206. '၉',
  207. '၀',
  208. 'း',
  209. '့',
  210. '။',
  211. '၊',
  212. ];
  213. /**
  214. * 罗马巴利字母映射表
  215. */
  216. private const ROMAN_CHARS = [
  217. 'ndra',
  218. 'kh',
  219. 'gh',
  220. 'ch',
  221. 'jh',
  222. 'ññ',
  223. 'ṭh',
  224. 'ḍh',
  225. 'th',
  226. 'dh',
  227. 'ph',
  228. 'bh',
  229. 'k',
  230. 'g',
  231. 'c',
  232. 'j',
  233. 'ñ',
  234. 'ḷ',
  235. 'ṭ',
  236. 'ḍ',
  237. 'ṇ',
  238. 't',
  239. 'd',
  240. 'n',
  241. 'h',
  242. 'p',
  243. 'b',
  244. 'm',
  245. 'y',
  246. 'r',
  247. 'l',
  248. 'v',
  249. 's',
  250. 'ṅ',
  251. 'ṅ',
  252. 'ssa',
  253. 'kha',
  254. 'gha',
  255. 'cha',
  256. 'jha',
  257. 'jha',
  258. 'ñña',
  259. 'ṭha',
  260. 'ḍha',
  261. 'tha',
  262. 'dha',
  263. 'pha',
  264. 'bha',
  265. 'ka',
  266. 'ga',
  267. 'ca',
  268. 'ja',
  269. 'ña',
  270. 'ḷa',
  271. 'ṭa',
  272. 'ḍa',
  273. 'ṇa',
  274. 'ta',
  275. 'da',
  276. 'na',
  277. 'ha',
  278. 'pa',
  279. 'ba',
  280. 'ma',
  281. 'ya',
  282. 'ra',
  283. 'ra',
  284. 'la',
  285. 'va',
  286. 'sa',
  287. 'ya',
  288. 'va',
  289. 'ra',
  290. 'ra',
  291. '្ta',
  292. '្tha',
  293. '្da',
  294. '្dha',
  295. '្ṭa',
  296. '្ṭha',
  297. '្ka',
  298. '្kha',
  299. '្ga',
  300. '្gha',
  301. '្pa',
  302. '្pha',
  303. '្ba',
  304. '្bha',
  305. '្ca',
  306. '្cha',
  307. '្ja',
  308. '្jha',
  309. '្a',
  310. '្ya',
  311. '្la',
  312. '្ma',
  313. '្va',
  314. '្ha',
  315. 'ssa',
  316. 'na',
  317. 'ta',
  318. 'ṭṭha',
  319. 'ṭṭa',
  320. 'ḍḍha',
  321. 'ḍḍa',
  322. 'ṇḍa',
  323. 'ṅka',
  324. 'ṅga',
  325. 'ṅkha',
  326. 'ṅgha',
  327. 'ha',
  328. 'iṃ',
  329. 'uṃ',
  330. 'o',
  331. 'o',
  332. 'aṃ',
  333. 'iṃ',
  334. 'uṃ',
  335. 'aṃ',
  336. 'ā',
  337. 'ā',
  338. 'i',
  339. 'ī',
  340. 'u',
  341. 'u',
  342. 'ū',
  343. 'e',
  344. 'ā',
  345. 'ā',
  346. 'a',
  347. 'i',
  348. 'ī',
  349. 'u',
  350. 'ū',
  351. 'e',
  352. 'o',
  353. 'n',
  354. 'ñ',
  355. '',
  356. '',
  357. 'aṃ',
  358. 'sse',
  359. 'khe',
  360. 'ghe',
  361. 'che',
  362. 'jhe',
  363. 'ññe',
  364. 'ṭhe',
  365. 'ḍhe',
  366. 'the',
  367. 'dhe',
  368. 'phe',
  369. 'bhe',
  370. 'ke',
  371. 'ge',
  372. 'ce',
  373. 'je',
  374. 'ñe',
  375. 'ḷe',
  376. 'ṭe',
  377. 'ḍe',
  378. 'ṇe',
  379. 'te',
  380. 'de',
  381. 'ne',
  382. 'he',
  383. 'pe',
  384. 'be',
  385. 'me',
  386. 'ye',
  387. 're',
  388. 'le',
  389. 've',
  390. 'se',
  391. 'ye',
  392. 've',
  393. 're',
  394. 'e',
  395. 'o',
  396. '1',
  397. '2',
  398. '3',
  399. '4',
  400. '5',
  401. '6',
  402. '7',
  403. '8',
  404. '9',
  405. '0',
  406. '"',
  407. "'",
  408. '.',
  409. ',',
  410. ];
  411. /**
  412. * 泰文字母映射表
  413. */
  414. private const THAI_CHARS = [
  415. 'นฺทฺร',
  416. 'ขฺ',
  417. 'ฆฺ',
  418. 'ฉฺ',
  419. 'ฌฺ',
  420. 'ญฺ',
  421. 'ฐฺ',
  422. 'ฑฺ',
  423. 'ถฺ',
  424. 'ธฺ',
  425. 'ผฺ',
  426. 'ภฺ',
  427. 'กฺ',
  428. 'คฺ',
  429. 'จฺ',
  430. 'ชฺ',
  431. 'ญฺ',
  432. 'ฬฺ',
  433. 'ฏฺ',
  434. 'ฑฺ',
  435. 'ณฺ',
  436. 'ตฺ',
  437. 'ทฺ',
  438. 'นฺ',
  439. 'หฺ',
  440. 'ปฺ',
  441. 'พฺ',
  442. 'มฺ',
  443. 'ยฺ',
  444. 'รฺ',
  445. 'ลฺ',
  446. 'วฺ',
  447. 'สฺ',
  448. 'งฺ',
  449. 'งฺ',
  450. 'สฺส',
  451. 'ข',
  452. 'ฆ',
  453. 'ฉ',
  454. 'ฌ',
  455. 'ฌ',
  456. 'ญฺญ',
  457. 'ฐ',
  458. 'ฑ',
  459. 'ถ',
  460. 'ธ',
  461. 'ผ',
  462. 'ภ',
  463. 'ก',
  464. 'ค',
  465. 'จ',
  466. 'ช',
  467. 'ญ',
  468. 'ฬ',
  469. 'ฏ',
  470. 'ฑ',
  471. 'ณ',
  472. 'ต',
  473. 'ท',
  474. 'น',
  475. 'ห',
  476. 'ป',
  477. 'พ',
  478. 'ม',
  479. 'ย',
  480. 'ร',
  481. 'ร',
  482. 'ล',
  483. 'ว',
  484. 'ส',
  485. 'ฺย',
  486. 'ฺว',
  487. 'ฺร',
  488. 'ร',
  489. 'ตฺต',
  490. 'ตฺถ',
  491. 'ทฺท',
  492. 'ทฺธ',
  493. 'ฏฺฏ',
  494. 'ฏฺฐ',
  495. 'กฺก',
  496. 'ขฺข',
  497. 'คฺค',
  498. 'ฆฺฆ',
  499. 'ปฺป',
  500. 'ผฺผ',
  501. 'พฺพ',
  502. 'ภฺภ',
  503. 'จฺจ',
  504. 'ฉฺฉ',
  505. 'ชฺช',
  506. 'ฌฺฌ',
  507. 'ฺ',
  508. 'ฺย',
  509. 'ฺล',
  510. 'ฺม',
  511. 'ฺว',
  512. 'ฺห',
  513. 'สฺส',
  514. 'น',
  515. 'ต',
  516. 'ฏฺฐ',
  517. 'ฏฺฏ',
  518. 'ฑฺฒ',
  519. 'ฑฺฑ',
  520. 'ณฺฑ',
  521. 'งฺก',
  522. 'งฺค',
  523. 'งฺข',
  524. 'งฺฆ',
  525. 'ห',
  526. 'ิํ',
  527. 'ุํ',
  528. 'โอ',
  529. 'โอ',
  530. 'อํ',
  531. 'อิํ',
  532. 'อุํ',
  533. 'ํ',
  534. 'า',
  535. 'า',
  536. 'ิ',
  537. 'ี',
  538. 'ุ',
  539. 'ุ',
  540. 'ู',
  541. 'เ',
  542. 'อา',
  543. 'อา',
  544. 'อ',
  545. 'อิ',
  546. 'อี',
  547. 'อุ',
  548. 'อู',
  549. 'เอ',
  550. 'โอ',
  551. 'น',
  552. 'ญ',
  553. '',
  554. 'ฺ',
  555. 'ํ',
  556. 'เสฺส',
  557. 'เข',
  558. 'เฆ',
  559. 'เฉ',
  560. 'เฌ',
  561. 'เญฺญ',
  562. 'เฐ',
  563. 'เฑ',
  564. 'เถ',
  565. 'เธ',
  566. 'เผ',
  567. 'เภ',
  568. 'เก',
  569. 'เค',
  570. 'เจ',
  571. 'เช',
  572. 'เญ',
  573. 'เฬ',
  574. 'เฏ',
  575. 'เฑ',
  576. 'เณ',
  577. 'เต',
  578. 'เท',
  579. 'เน',
  580. 'เห',
  581. 'เป',
  582. 'เพ',
  583. 'เม',
  584. 'เย',
  585. 'เร',
  586. 'เล',
  587. 'เว',
  588. 'เส',
  589. 'เย',
  590. 'เว',
  591. 'เร',
  592. 'เอ',
  593. 'โอ',
  594. '๑',
  595. '๒',
  596. '๓',
  597. '๔',
  598. '๕',
  599. '๖',
  600. '๗',
  601. '๘',
  602. '๙',
  603. '๐',
  604. 'ํ',
  605. 'ฺ',
  606. 'ฯ',
  607. 'ฯลฯ',
  608. ];
  609. /**
  610. * 缅文转罗马巴利
  611. */
  612. public function myanmarToRoman(string $input): string
  613. {
  614. return str_replace(self::MYANMAR_CHARS, self::ROMAN_CHARS, $input);
  615. }
  616. /**
  617. * 罗马巴利转缅文
  618. */
  619. public function romanToMyanmar(string $input): string
  620. {
  621. // 手动构建映射数组,遇到重复的键时保留第一个
  622. $mapping = [];
  623. foreach (self::ROMAN_CHARS as $index => $roman) {
  624. if (! isset($mapping[$roman])) {
  625. $mapping[$roman] = self::MYANMAR_CHARS[$index];
  626. }
  627. }
  628. // 按键长度降序排序,优先匹配较长的字符串
  629. uksort($mapping, function ($a, $b) {
  630. $lenDiff = strlen($b) - strlen($a);
  631. if ($lenDiff !== 0) {
  632. return $lenDiff;
  633. }
  634. return strcmp($a, $b);
  635. });
  636. return str_replace(array_keys($mapping), array_values($mapping), $input);
  637. }
  638. /**
  639. * 泰文转罗马巴利
  640. */
  641. public function thaiToRoman(string $input): string
  642. {
  643. return str_replace(self::THAI_CHARS, self::ROMAN_CHARS, $input);
  644. }
  645. /**
  646. * 罗马巴利转泰文
  647. */
  648. public function romanToThai(string $input): string
  649. {
  650. // 手动构建映射数组,遇到重复的键时保留第一个
  651. $mapping = [];
  652. foreach (self::ROMAN_CHARS as $index => $roman) {
  653. if (! isset($mapping[$roman])) {
  654. $mapping[$roman] = self::THAI_CHARS[$index];
  655. }
  656. }
  657. // 按键长度降序排序,优先匹配较长的字符串
  658. uksort($mapping, function ($a, $b) {
  659. $lenDiff = strlen($b) - strlen($a);
  660. if ($lenDiff !== 0) {
  661. return $lenDiff;
  662. }
  663. return strcmp($a, $b);
  664. });
  665. return str_replace(array_keys($mapping), array_values($mapping), $input);
  666. }
  667. /**
  668. * 缅文转泰文
  669. */
  670. public function myanmarToThai(string $input): string
  671. {
  672. $roman = $this->myanmarToRoman($input);
  673. return $this->romanToThai($roman);
  674. }
  675. /**
  676. * 泰文转缅文
  677. */
  678. public function thaiToMyanmar(string $input): string
  679. {
  680. $roman = $this->thaiToRoman($input);
  681. return $this->romanToMyanmar($roman);
  682. }
  683. /**
  684. * 自动检测并转换为罗马巴利
  685. */
  686. public function toRoman(string $input): string
  687. {
  688. // 检测是否包含缅文字符
  689. if (preg_match('/[\x{1000}-\x{109F}]/u', $input)) {
  690. return $this->myanmarToRoman($input);
  691. }
  692. // 检测是否包含泰文字符
  693. if (preg_match('/[\x{0E00}-\x{0E7F}]/u', $input)) {
  694. return $this->thaiToRoman($input);
  695. }
  696. // 默认返回原文
  697. return $input;
  698. }
  699. }