RomanizeService.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  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. * @param string $input
  613. * @return string
  614. */
  615. public function myanmarToRoman(string $input): string
  616. {
  617. return str_replace(self::MYANMAR_CHARS, self::ROMAN_CHARS, $input);
  618. }
  619. /**
  620. * 罗马巴利转缅文
  621. *
  622. * @param string $input
  623. * @return string
  624. */
  625. public function romanToMyanmar(string $input): string
  626. {
  627. // 手动构建映射数组,遇到重复的键时保留第一个
  628. $mapping = [];
  629. foreach (self::ROMAN_CHARS as $index => $roman) {
  630. if (!isset($mapping[$roman])) {
  631. $mapping[$roman] = self::MYANMAR_CHARS[$index];
  632. }
  633. }
  634. // 按键长度降序排序,优先匹配较长的字符串
  635. uksort($mapping, function ($a, $b) {
  636. $lenDiff = strlen($b) - strlen($a);
  637. if ($lenDiff !== 0) {
  638. return $lenDiff;
  639. }
  640. return strcmp($a, $b);
  641. });
  642. return str_replace(array_keys($mapping), array_values($mapping), $input);
  643. }
  644. /**
  645. * 泰文转罗马巴利
  646. *
  647. * @param string $input
  648. * @return string
  649. */
  650. public function thaiToRoman(string $input): string
  651. {
  652. return str_replace(self::THAI_CHARS, self::ROMAN_CHARS, $input);
  653. }
  654. /**
  655. * 罗马巴利转泰文
  656. *
  657. * @param string $input
  658. * @return string
  659. */
  660. public function romanToThai(string $input): string
  661. {
  662. // 手动构建映射数组,遇到重复的键时保留第一个
  663. $mapping = [];
  664. foreach (self::ROMAN_CHARS as $index => $roman) {
  665. if (!isset($mapping[$roman])) {
  666. $mapping[$roman] = self::THAI_CHARS[$index];
  667. }
  668. }
  669. // 按键长度降序排序,优先匹配较长的字符串
  670. uksort($mapping, function ($a, $b) {
  671. $lenDiff = strlen($b) - strlen($a);
  672. if ($lenDiff !== 0) {
  673. return $lenDiff;
  674. }
  675. return strcmp($a, $b);
  676. });
  677. return str_replace(array_keys($mapping), array_values($mapping), $input);
  678. }
  679. /**
  680. * 缅文转泰文
  681. *
  682. * @param string $input
  683. * @return string
  684. */
  685. public function myanmarToThai(string $input): string
  686. {
  687. $roman = $this->myanmarToRoman($input);
  688. return $this->romanToThai($roman);
  689. }
  690. /**
  691. * 泰文转缅文
  692. *
  693. * @param string $input
  694. * @return string
  695. */
  696. public function thaiToMyanmar(string $input): string
  697. {
  698. $roman = $this->thaiToRoman($input);
  699. return $this->romanToMyanmar($roman);
  700. }
  701. /**
  702. * 自动检测并转换为罗马巴利
  703. *
  704. * @param string $input
  705. * @return string
  706. */
  707. public function toRoman(string $input): string
  708. {
  709. // 检测是否包含缅文字符
  710. if (preg_match('/[\x{1000}-\x{109F}]/u', $input)) {
  711. return $this->myanmarToRoman($input);
  712. }
  713. // 检测是否包含泰文字符
  714. if (preg_match('/[\x{0E00}-\x{0E7F}]/u', $input)) {
  715. return $this->thaiToRoman($input);
  716. }
  717. // 默认返回原文
  718. return $input;
  719. }
  720. }