Skip to content

Kaikki WordPressistä, web-kehityksestä — ja paljon muuta

🔢 Numeroiden kääntäminen PHP:llä ja JavaScriptillä: arabialaiset numerot devanagariksi ja takaisin

🔢 Numeroiden kääntäminen PHP:llä ja JavaScriptillä: arabialaiset numerot devanagariksi ja takaisin

Täytät lomaketta verkkosivustolla, ja numerot muuttuvat lukukelvottomiksi merkeiksi. Tämä on tuttu tilanne kaikille monikielisten projektien parissa työskenteleville: verkkokaupan nepalinkielinen versio näyttää hinnat muodossa अक्षर, ja yhteydenottolomake epäonnistuu validoinnissa "väärien" numeroiden takia.

Ongelma on siinä, että eri kielet käyttävät eri numerojärjestelmiä. Englanti ja venäjä käyttävät arabialaisia numeroita (0-9). Hindi, nepali ja marathi käyttävät devanagari-symboleja (०-९). PHP ja JavaScript eivät vaihda niiden välillä automaattisesti. Tehtävä on kuitenkin ratkaistavissa ilman yhtäkään ulkoista kirjastoa, pelkkiä sisäänrakennettuja merkkijonofunktioita käyttäen. Ei asennettavia riippuvuuksia, ei kolmannen osapuolen rajapintoja.

Alla on kaksi valmista koodinpätkää, jotka ratkaisevat tämän ongelman viidessä minuutissa. Ei kehyksiä, ei Composer-paketteja, ei npm-riippuvuuksia, pelkkää puhdasta PHP:tä ja vanilla JavaScriptiä. Kopioi ne, vaihda omat symbolisi, ja se toimii.

💡 Nopea yleiskatsaus:

  • Kopioi PHP-funktio teemasi functions.php-tiedostoon tai Code Snippets -lisäosan kautta; se muuntaa arabialaiset numerot devanagari-numeroiksi ja takaisin
  • Käytä frontendissä valmista JavaScript-koodia, jossa on sanakirjaolioita lennossa tapahtuvaa muuntamista varten suoraan syötekentässä
  • Korvaaminen käyttää glyyfien vastaavuustaulukkoa matematiikan sijaan, mikä tekee menetelmästä yleispätevän mille tahansa kirjoitusjärjestelmälle
  • Testaa: syötä 1234 ja saat tulokseksi १२३४, ja päinvastoin; molemmat suunnat toimivat symmetrisesti

Miten numerojärjestelmät toimivat eri kielissä

Useimmat verkkosivustot käyttävät arabialaisia numeroita: 0 1 2 3 4 5 6 7 8 9. Historiallisesti tämä järjestelmä tuli Intiasta, mutta levisi laajalle arabimaailman kautta, mistä johtuu nimi.

Vaihtoehtoisia merkistöjä on kymmenissä kirjoitusjärjestelmissä. Devanagari (hindi, nepali, marathi) käyttää omaa sarjaansa: ० १ २ ३ ४ ५ ६ ७ ८ ९. Itäarabialaiset numerot (arabia, persia, urdu) käyttävät eri merkistöä: ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩. Bengalilaisilla, thai- ja khmer-numeroilla on kullakin omat glyyfinsä ja omat Unicode-alueensa. Tällaisia järjestelmiä on yhteensä yli kaksikymmentä.

Mutta numeerinen arvo pysyy samana. 5, ja ٥ ovat kaikki sama numero "viisi", vain kirjoitettuna eri symbolein. Siksi järjestelmien välinen kääntäminen on glyyfien korvaamista vastaavuustaulukon avulla, ei matemaattista muuntamista. Mitään ei tarvitse laskea uudelleen; täytyy vain tietää oikeat symboliparit.

Juuri tähän periaatteeseen alla oleva koodi perustuu.

Vaihe 1: Numeroiden muuntaminen PHP:llä

Ohjelmoija työskentelee kannettavalla koodieditori auki

PHP-lähestymistapa on niin yksinkertainen kuin olla voi: str_replace()-funktio ottaa kaksi taulukkoa, mitä etsitään ja millä korvataan. Merkkijono käsitellään yhdellä kertaa, ja kaikki osumat korvataan.

Lisää tämä koodi lapsiteemasi functions.php-tiedostoon tai Code Snippets -lisäosan kautta. Funktio hyväksyy numeron tai numeroita sisältävän merkkijonon ja palauttaa tuloksen devanagari-symbolein.

1<?php
2/**
3 * Converts Arabic numerals to Devanagari characters (Hindi, Nepali).
4 *
5 * @param string|int $input String or number to convert.
6 * @return string String with Devanagari numerals.
7 */
8function convert_to_devanagari($input) {
9 $english = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
10 $devanagari = array("०", "१", "२", "३", "४", "५", "६", "७", "८", "९");
11
12 return str_replace($english, $devanagari, (string) $input);
13}
14
15/* Usage example */
16echo convert_to_devanagari(2026);
17// Output: २०२६
18?>

Mitä tässä tapahtuu: str_replace() käy läpi $english-taulukon, ja kutakin alkiota (esimerkiksi "2") kohden se korvaa sen vastaavalla alkiolla $devanagari-taulukosta ("२"). Muuntaminen (string)-tyypiksi varmistaa, että funktio toimii sekä numeroilla että merkkijonoilla.

Käänteinen muunnos, devanagari-numeroista arabialaisiksi numeroiksi, tehdään vaihtamalla taulukoiden paikkaa:

1<?php
2/**
3 * Converts Devanagari characters back to Arabic numerals.
4 *
5 * @param string $input String with Devanagari numerals.
6 * @return string String with Arabic numerals.
7 */
8function convert_from_devanagari($input) {
9 $english = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
10 $devanagari = array("०", "१", "२", "३", "४", "५", "६", "७", "८", "९");
11
12 return str_replace($devanagari, $english, $input);
13}
14
15/* Example */
16echo convert_from_devanagari('२०२६');
17// Output: 2026
18?>

Taulukot ovat samat; vain argumenttien järjestys muuttuu. Ensimmäinen taulukko sisältää nyt devanagari-symbolit (mitä etsimme), toinen arabialaiset numerot (millä korvaamme).

Missä käyttää. Funktio on hyödyllinen kaikkialla teemassa, missä numeroita näytetään: tuotteiden hinnat WooCommercessa, päivämäärät blogikirjoituksissa, sivutus. Kääri kutsu kaikkialle, missä tarvitset numeroiden lokalisointia tietylle yleisölle.

Reunatapausten käsittely PHP:ssä

convert_to_devanagari()-funktio hyväksyy tyypit string|int, mutta käytännössä syöte voi olla mitä tahansa. Mitä tapahtuu, jos sille antaa null-arvon, tyhjän merkkijonon tai merkkijonon, jossa ei ole numeroita? (string) null palauttaa tyhjän merkkijonon, ja str_replace() tyhjällä merkkijonolla palauttaa myös tyhjän ilman virheitä. Merkkijono ilman numeroita (esimerkiksi "Hello") palautuu muuttumattomana, koska korvaaminen ei löydä osumia.

Jos numero sisältää erottimia (pilkku tuhansille, piste desimaaleille), ne pysyvät paikallaan; vain itse numerot korvataan. Liukuluvuille tämä toiminta on oikea, mutta jos numerojen muotoilulla on väliä ja erottimien tulisi muuttua lokaalin mukaan, lisää erillinen käsittely number_format()-funktiolla ennen muuntamista.

Erittäin pitkille numeroille (esimerkiksi 20-numeroiset tunnisteet) lähestymistapa toimii ilman muutoksia: str_replace() käsittelee minkä tahansa pituisia merkkijonoja, rajoitteena vain käytettävissä oleva PHP-muisti. Devanagari-merkit vievät kukin 3 tavua UTF-8:ssa, joten tuloksena oleva merkkijono on tavuina pidempi kuin alkuperäinen. Merkkien laskemiseen käytä mb_strlen(), älä strlen().

Vaihe 2: Numeroiden muuntaminen JavaScriptillä

Frontendissä sama logiikka toteutetaan käyttämällä sanakirjaolioita ja String.replace()-metodia säännöllisen lausekkeen kanssa. Tämä on kätevää dynaamisissa käyttöliittymissä: käyttäjä syöttää numeron kenttään, ja skripti näyttää välittömästi devanagari-vastineen.

Sijoita tämä koodi erilliseen .js-tiedostoon teemassasi tai wp_add_inline_script-funktion kautta functions.php-tiedostossa. Ei riippuvuuksia, puhdasta ES5:tä, toimii jopa vanhoissa selaimissa.

1/**
2 * Dictionaries for translating between Arabic numerals and Devanagari.
3 */
4var englishToDevanagari = {
5 '0': '०', '1': '१', '2': '२', '3': '३', '4': '४',
6 '5': '५', '6': '६', '7': '७', '8': '८', '9': '९'
7};
8
9var devanagariToEnglish = {
10 '०': '0', '१': '1', '२': '2', '३': '3', '४': '4',
11 '५': '5', '६': '6', '७': '7', '८': '8', '९': '9'
12};
13
14/**
15 * Converts Arabic numerals in a string to Devanagari characters.
16 * @param {string|number} input
17 * @returns {string}
18 */
19function toDevanagari(input) {
20 return String(input).replace(/[0-9]/g, function(match) {
21 return englishToDevanagari[match];
22 });
23}
24
25/**
26 * Converts Devanagari characters to Arabic numerals.
27 * @param {string} input
28 * @returns {string}
29 */
30function fromDevanagari(input) {
31 return input.replace(/[०-९]/g, function(match) {
32 return devanagariToEnglish[match];
33 });
34}
35
36// Examples:
37console.log(toDevanagari(9857)); // ९८५७
38console.log(fromDevanagari('१२३४')); // 1234

Avainkohta on säännöllinen lauseke /[0-9]/g. g (global) -lippu saa replace()-metodin käsittelemään jokaisen numeron merkkijonossa, ei vain ensimmäistä. Anonyymi takaisinkutsufunktio vastaanottaa täsmäävän merkin ja palauttaa sen vastineen sanakirjasta.

Devanagari-numeroille käytetään aluetta [०-९]; Unicodessa nämä merkit ovat peräkkäisiä, joten regex toimii oikein.

Missä käyttää. Reaaliaikainen syöttö lomakkeissa (muunnos lennossa kirjoittaessa), hintojen ja päivämäärien näyttäminen sivuston lokalisoiduissa versioissa, käänteinen muunnos ennen lomakkeen lähettämistä palvelimelle, jotta tietokantaan menee aina arabialaiset numerot.

Käytännön esimerkki: yhteydenottolomake lennossa tapahtuvalla muunnoksella

Yhdistetään molemmat lähestymistavat toimivaksi kokoonpanoksi. Oletetaan, että sivuston nepalinkielisessä versiossa on tilauslomake, johon käyttäjä syöttää summan devanagari-numeroin. Tehtävä: näytä syötetty numero molemmissa järjestelmissä tarkistusta varten ja lähetä arabialaiset numerot palvelimelle.

Lomakkeen merkintä sisältää <input>-elementin ja esikatselulohkon. Jokainen näppäimenpainallus kentässä laukaisee input-tapahtuman käsittelijän, joka kutsuu toDevanagari()-funktiota ja näyttää tuloksen viereisessä <span>-elementissä. Kun lomake lähetetään, fromDevanagari() suoritetaan, ja palvelimelle lähetettävä POST-pyynnön runko sisältää arabialaiset numerot. PHP-palvelinpuolen koodi vastaanottaa numeron vakiomuodossa ja käsittelee sitä tavalliseen tapaan ilman lisämuunnoksia.

Tämä sama malli soveltuu hintakenttiin, päivämääriin, puhelinnumeroihin ja kaikkiin muihin kenttiin, joissa käyttäjä odottaa näkevänsä oman numerojärjestelmänsä, kun taas järjestelmän on tallennettava yhtenäinen muoto. Muunnos vie mikrosekunteja eikä vaikuta käyttöliittymän responsiivisuuteen.

Katso myös: video numerojärjestelmistä ohjelmoinnissa

Laajempaa katsausta aiheeseen, miten numerojärjestelmät toimivat koodissa ja miten niiden välillä muunnetaan JavaScriptillä, tarjoaa tämä Techno Geekin erittely. Se kattaa binääri-, oktaali- ja desimaalijärjestelmät valmiin projektin kera.

⁉️🤔 Usein kysytyt kysymykset

Voiko tällä samalla menetelmällä muuntaa numeroita arabialaisiksi (itäarabialaiset symbolit)?

Kyllä. Korvaa devanagari-taulukko itäarabialaisilla symboleilla: array("٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"). Logiikka on sama: str_replace() PHP:ssä ja sanakirja regexin kanssa JS:ssä. Se mukautuu yhtä helposti bengalilaisiin, thai-, khmer- ja mihin tahansa muuhun kirjoitusjärjestelmään, jolla on omat numeroglyyfinsä.

Onko turvallista käyttää str_replace()-funktiota monitavuisille merkkijonoille PHP:ssä?

Kyllä, str_replace() toimii oikein UTF-8:n ja monitavuisten merkkien kanssa, toisin kuin strpos() tai substr(), jotka tarvitsevat mbstring-vastineet. Devanagari-symbolit (, ) vievät kukin 3 tavua UTF-8:ssa, mutta str_replace() käsittelee niitä tavuturvallisesti, koska se etsii tarkkoja binäärisiä sekvenssivastaavuuksia. Ongelmia ei tule.

Entä jos merkkijono sisältää sekoituksen arabialaisia numeroita ja devanagari-symboleja?

Molemmat funktiot käsittelevät vain omia alueitaan. Jos convert_to_devanagari() vastaanottaa merkkijonon "Price: 500 रुपय", numero 500 muuttuu muotoon ५००, kun taas teksti pysyy koskemattomana. Käänteinen funktio convert_from_devanagari() vaikuttaa vain devanagari-numeroihin. Sekalainen syöte käsitellään oikein automaattisesti.

Miten voin soveltaa muunnosta kaikkiin numeroihin WordPress-sivulla muokkaamatta jokaista mallipohjaa?

Käytä JavaScript-lähestymistapaa vaiheesta 2 ja suorita DOM-solmujen läpikäynti sivun latauksessa. Etsi kaikki numeroita sisältävät tekstisolmut (joko TreeWalker- tai rekursiivisen childNodes-läpikäynnin avulla) ja sovella toDevanagari()-funktiota niiden sisältöön. Palvelinpuolen PHP-lähestymistapaa varten käytä suodatinta the_content- tai gettext-koukussa, jos numerot on upotettu käännöksiin.

Mistä löydän merkkitaulukoita muille kirjoitusjärjestelmille?

Arvovaltainen lähde on Unicode Consortium. Devanagari-numeroille tämä on alue U+0966-U+096F. Itäarabialainen on U+0660-U+0669. Bengalilainen on U+09E6-U+09EF. Kopioi vain merkit taulukosta ja sijoita ne taulukoihin; koodia ei tarvitse muuttaa.

Lähestymistavan suorituskyky ja rajoitukset

str_replace() 10 alkion taulukoilla suorittaa täsmälleen 10 vertailua kutakin merkkijonon kohtaa kohden. Tyypilliselle 5-10 numeroa sisältävälle merkkijonolle tämä tarkoittaa 50-100 operaatiota; suoritusaika mitataan mikrosekunneissa. Vertailun vuoksi, preg_replace_callback()-funktiota säännöllisen lausekkeen kanssa käyttävä lähestymistapa lisää ylimääräistä kuormaa kuvion kääntämisestä ja takaisinkutsun kutsumisesta jokaiselle osumalle. Ero on huomaamaton pienillä merkkijonoilla, mutta str_replace() voittaa suurilla volyymeilla.

Lähestymistavan pääasiallinen rajoitus on, että se korvaa glyyfejä, ei numeron semantiikkaa. Jos tarvitset aritmetiikkaa devanagari-numeroilla (yhteenlaskua, kertolaskua), PHP ei tunnista devanagari-symboleja numeroiksi. Muunna aina arabialaisiksi numeroiksi ennen matemaattisia operaatioita ja muunna takaisin jälkeenpäin. Tämä ei ole menetelmän vika, vaan seuraus kirjoitusjärjestelmien ja numeeristen tietotyyppien välisestä erosta.

Toinen vivahde: menetelmä olettaa "yksi glyyfi, yksi numero" -vastaavuuden. Kirjoitusjärjestelmissä, joissa numerot kirjoitetaan yhdistelmä-ligatuureilla (kuten joissakin historiallisissa järjestelmissä), yksinkertainen korvausmenetelmä ei toimi. Mutta kaikille moderneille intialaisille kirjaimistoille (devanagari, bengali, gurmukhi, gujarati, odia, tamili, telugu, kannada, malajalam) sekä itäarabialaisille numeroille vastaavuus on tiukasti 1:1, ja menetelmä toimii moitteettomasti.

Mitä viedä tuotantoon: PHP, JavaScript vai molemmat?

PHP-ratkaisu on tapauksiin, joissa numerot on renderöitävä kohdesymbolijärjestelmässä palvelimella ennen HTML:n lähettämistä. Tämä on oikein hakukoneoptimoinnin kannalta: hakukone näkee sisällön välittömästi kohdelokaalissa, ei arabialaisina numeroina, jotka skripti sitten korvaa. WooCommerce-verkkokaupalle tämä tarkoittaa, että tuoteluettelon ja tuotesivujen hinnat indeksoidaan devanagari-numeroin, mikä vaikuttaa positiivisesti sijoitukseen nepalin- ja hindinkielisissä segmenteissä.

JavaScript-versio on dynaamista vuorovaikutusta varten: syötekenttä välittömällä esikatselulla, kielen vaihto ilman sivun uudelleenlatausta, lomaketietojen muuntaminen ennen lähetystä. Se on myös välttämätön single-page-sovelluksissa (SPA), joissa palvelin palauttaa JSONia arabialaisin numeroin ja frontend renderöi ne käyttäjän lokaalissa.

Käytännössä yhdistelmä toimii hyvin: PHP renderöi sivun lokalisoiduin numeroin indeksointia varten, kun taas JavaScript käsittelee käyttäjän syötteen ja muuntaa edestakaisin lennossa. Molemmat koodinpätkät, ilman ulkoisia riippuvuuksia, ovat yhteensä alle 40 riviä, ja ne ratkaisevat tehtävän täysin mille tahansa kirjoitusjärjestelmälle, jolla on omat numeroglyyfinsä.

Ennen tuotantoon vientiä testaa kolme skenaariota: suora funktiokutsu numerolla, merkkijono sekasisällöllä (numeroita ja tekstiä) ja käänteinen muunnos. Varmista, että arabialaiset numerot saapuvat aina palvelimelle ja käyttöliittymä näyttää käyttäjälle järjestelmän, joka vastaa tämän kieliodotuksia. Viisi minuuttia testausta säästää tunteja debuggausta live-liikenteessä.

Kopioi molemmat koodinpätkät projektiisi, korvaa tarvittavat symbolit Unicode-taulukosta kirjoitusjärjestelmällesi, ja tehtävä on suoritettu. Kaikki tarvittava on jo sisäänrakennettuna kieleen.