Skip to content

Kõik WordPressist, veebiarendusest — ja mitte ainult

🔢 Numbritõlge PHP ja JavaScriptiga: araabia numbrid devanaagarisse ja tagasi

🔢 Numbritõlge PHP ja JavaScriptiga: araabia numbrid devanaagarisse ja tagasi

Kasutaja täidab veebisaidil vormi ja numbrid muutuvad loetamatuteks märkideks. See on tuttav olukord kõigile, kes töötavad mitmekeelsete projektidega: veebipoe nepali versioon näitab hindu अक्षर-märkides ja kontaktivorm ei läbi valideerimist „valede" numbrite tõttu.

Probleem on selles, et erinevad keeled kasutavad erinevaid numbrisüsteeme. Inglise ja vene keel kasutavad araabia numbreid (0-9). Hindi, nepali ja marathi keel kasutavad devanaagari sümboleid (०-९). PHP ja JavaScript ei lülitu nende vahel automaatselt. Ometi saab ülesande lahendada ilma ühegi välise teegita, kasutades ainult sisseehitatud stringifunktsioone. Pole vaja installida sõltuvusi ega kasutada kolmandate osapoolte API-sid.

Allpool on kaks kasutusvalmis koodinäidet, mis lahendavad selle probleemi 5 minutiga. Ei mingeid raamistikke, Composer'i pakette ega npm sõltuvusi, lihtsalt puhas PHP ja vanilla JavaScript. Kopeeri need, asenda sümbolid ja see töötab.

💡 Kiire ülevaade:

  • Kopeeri PHP funktsioon oma teema faili functions.php või Code Snippets pluginaga; see teisendab araabia numbrid devanaagari numbriteks ja vastupidi
  • Esiküljel kasuta valmis JavaScript koodi sõnastikuobjektidega, et teisendada numbreid sisestusväljal jooksvalt
  • Asendamine kasutab matemaatika asemel märgivastavuste tabelit, muutes meetodi universaalseks iga kirjasüsteemi jaoks
  • Testi seda: sisesta 1234 ja saad १२३४ ning vastupidi; mõlemad suunad töötavad sümmeetriliselt

Kuidas numbrisüsteemid erinevates keeltes töötavad

Enamik veebisaite töötab araabia numbritega: 0 1 2 3 4 5 6 7 8 9. Ajalooliselt pärineb see süsteem Indiast, kuid levis laialt araabia maailma kaudu, sellest ka nimi.

Alternatiivseid komplekte on kümnetes kirjasüsteemides. Devanaagari (hindi, nepali, marathi) kasutab oma seeriat: ० १ २ ३ ४ ५ ६ ७ ८ ९. Idapoolsed araabia numbrid (araabia, pärsia, urdu) kasutavad teistsugust komplekti: ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩. Bengali, tai ja khmeeri keelel on igaühel oma märgid ja oma Unicode'i vahemikud. Kokku on selliseid süsteeme üle kahekümne.

Kuid numbriline väärtus jääb samaks. 5, ja ٥ on kõik sama number "viis", lihtsalt kirjutatud erinevate sümbolitega. Seetõttu on süsteemide vaheline tõlge vastavustabelit kasutav märgiasendus, mitte matemaatiline teisendus. Midagi pole vaja ümber arvutada; pead lihtsalt teadma õigeid sümbolipaare.

Just see põhimõte on alloleva koodi aluseks.

Samm 1: Numbrite teisendamine PHP-ga

Programmeerija töötab sülearvutiga, koodiredaktor avatud

PHP lähenemine on nii lihtne kui võimalik: funktsioon str_replace() võtab kaks massiivi, mida otsida ja millega asendada. Stringi töödeldakse ühe käiguga ja kõik vasted asendatakse.

Lisa see kood oma alamteema faili functions.php või Code Snippets pluginaga. Funktsioon võtab vastu numbri või numbreid sisaldava stringi ja tagastab tulemuse devanaagari sümbolitega.

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?>

Mis siin toimub: str_replace() itereerib läbi $english massiivi ja iga elemendi (näiteks "2") jaoks asendab vastava elemendi $devanagari massiivist ("२"). (string)-iks teisendamine tagab, et funktsioon töötab nii numbrite kui ka stringidega.

Vastupidine teisendus devanaagarist araabia numbriteks toimub massiive vahetades:

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?>

Massiivid on samad; muutub ainult argumentide järjekord. Esimene massiiv sisaldab nüüd devanaagari sümboleid (mida otsime), teine araabia numbreid (millega asendame).

Kus kasutada. Funktsioon on kasulik kõikjal teemas, kus kuvatakse numbreid: toodete hinnad WooCommerce'is, kuupäevad blogipostitustes, lehekülgede nummerdus. Lisa väljakutse kohta, kus vajad numbrite lokaliseerimist konkreetsele sihtrühmale.

Piirjuhtumite käsitlemine PHP-s

Funktsioon convert_to_devanagari() võtab vastu string|int, kuid praktikas võib sisend olla ükskõik mis. Mis juhtub, kui sisestad null, tühja stringi või stringi ilma numbriteta? (string) null tagastab tühja stringi ja str_replace() tühja stringiga tagastab samuti tühja ilma vigadeta. Numbriteta string (näiteks "Hello") tagastatakse muutmata kujul, kuna asendus ei leia vasteid.

Kui number sisaldab eraldajaid (komad tuhandete jaoks, punkt kümnendkohtade jaoks), jäävad need alles; asendatakse ainult numbrid ise. Ujukomaarvude puhul on see käitumine korrektne, kuid kui numbri vorming on oluline ja eraldajad peaksid muutuma vastavalt lokaadile, lisa enne teisendamist eraldi töötlus number_format() abil.

Väga pikkade numbrite (näiteks 20-kohalised identifikaatorid) puhul töötab lähenemine muudatusteta: str_replace() töötleb mis tahes pikkusega stringe, piiratuna ainult saadaoleva PHP mäluga. Devanaagari märgid võtavad UTF-8-s igaüks 3 baiti, seega on tulemuseks olev string baitides pikem kui originaal. Märkide loendamiseks kasuta mb_strlen(), mitte strlen().

Samm 2: Numbrite teisendamine JavaScriptiga

Esiküljel rakendatakse sama loogikat sõnastikuobjektide ja String.replace() meetodi abil koos regulaaravaldisega. See on mugav dünaamiliste liideste jaoks: kasutaja sisestab numbri väljale ja skript näitab koheselt devanaagari vastet.

Paiguta see kood oma teemas eraldi .js faili või functions.php-s wp_add_inline_script kaudu. Sõltuvused puuduvad, tavaline ES5, töötab isegi vanades brauserites.

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

Võtmepunkt on regulaaravaldis /[0-9]/g. Lipp g (globaalne) paneb replace() töötlema iga numbrit stringis, mitte ainult esimest. Anonüümne callback-funktsioon võtab vastu leitud märgi ja tagastab selle vaste sõnastikust.

Devanaagari numbrite jaoks kasutatakse vahemikku [०-९]; Unicode'is on need märgid järjestikused, seega töötab regex korrektselt.

Kus kasutada. Reaalajas sisestus vormides (teisendus jooksvalt tippimise ajal), hindade ja kuupäevade kuvamine saidi lokaliseeritud versioonides, vastupidine teisendus enne vormi serverisse saatmist, nii et andmebaasi jõuavad alati araabia numbrid.

Praktiline näide: kontaktivorm jooksva teisendusega

Ühendame mõlemad lähenemised toimivaks seadistuseks. Oletame, et saidi nepali versioonil on tellimisvorm, kus kasutaja sisestab summa devanaagari numbrites. Ülesanne: näidata sisestatud numbrit mõlemas süsteemis kontrollimiseks ja saata serverisse araabia numbrid.

Vormi märgistus sisaldab <input> elementi ja eelvaate plokki. Igal klahvivajutusel väljal käivitub input sündmuse töötleja, mis kutsub välja toDevanagari() ja kuvab tulemuse külgnevas <span> elemendis. Vormi saatmisel käivitub fromDevanagari() ja serverisse saadetava POST päringu keha sisaldab araabia numbreid. PHP serveripoolne kood võtab numbri vastu standardses vormingus ja töötab sellega nagu tavaliselt, ilma täiendava teisenduseta.

Sama muster kehtib hinnaväljade, kuupäevade, telefoninumbrite ja kõigi muude väljade kohta, kus kasutaja eeldab oma kohalikku numbrisüsteemi, samas kui süsteem peab salvestama ühtse vormingu. Teisendus võtab mikrosekundeid ega mõjuta liidese reageerimisvõimet.

Vaata ka: video numbrisüsteemidest programmeerimises

Laiema ülevaate saamiseks sellest, kuidas numbrisüsteemid koodis töötavad ja kuidas nende vahel JavaScriptis teisendada, vaata seda Techno Geek'i analüüsi. See hõlmab kahend-, kaheksand- ja kümnendsüsteeme koos valmis projektiga.

⁉️🤔 Korduma kippuvad küsimused

Kas sama meetodiga saab teisendada numbreid araabia (idapoolsed araabia sümbolid) numbriteks?

Jah. Asenda devanaagari massiiv idapoolsete araabia sümbolitega: array("٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"). Loogika on sama: str_replace() PHP-s ja sõnastik koos regexiga JS-is. See kohandub sama lihtsalt ka bengali, tai, khmeeri ja mis tahes muu kirjasüsteemi jaoks, millel on oma numbrilised märgid.

Kas str_replace() kasutamine mitmebaidiste stringide jaoks PHP-s on ohutu?

Jah, str_replace() töötab UTF-8 ja mitmebaidiste märkidega korrektselt, erinevalt strpos() või substr() funktsioonidest, mis vajavad mbstring ekvivalente. Devanaagari sümbolid (, ) võtavad UTF-8-s igaüks 3 baiti, kuid str_replace() käsitleb neid baitide suhtes ohutult, sest see otsib täpseid binaarjada vasteid. Probleeme ei teki.

Mis siis, kui string sisaldab segu araabia numbritest ja devanaagari sümbolitest?

Mõlemad funktsioonid töötlevad ainult oma vastavaid vahemikke. Kui convert_to_devanagari() saab stringi "Price: 500 रुपय", muutub number 500 -> ५००, samas kui tekst jääb puutumata. Vastupidine funktsioon convert_from_devanagari() mõjutab ainult devanaagari numbreid. Segasisendit käsitletakse automaatselt korrektselt.

Kuidas rakendada teisendust kõigile numbritele WordPressi lehel ilma iga malli redigeerimata?

Kasuta 2. sammu JavaScript lähenemist ja käivita lehe laadimisel DOM-sõlmede läbimine. Leia kõik tekstisõlmed, mis sisaldavad numbreid (kasutades TreeWalker või rekursiivset childNodes läbimist) ja rakenda nende sisule toDevanagari(). Serveripoolse PHP lähenemise jaoks kasuta filtrit the_content või gettext, kui numbrid on tõlgetesse põimitud.

Kust leida märgitabeleid teiste kirjasüsteemide jaoks?

Autoriteetne allikas on Unicode Consortium. Devanaagari numbrite jaoks on see vahemik U+0966-U+096F. Idapoolne araabia on U+0660-U+0669. Bengali on U+09E6-U+09EF. Lihtsalt kopeeri märgid tabelist ja asenda need massiividesse; koodi pole vaja muuta.

Lähenemise jõudlus ja piirangud

str_replace() 10 elemendiga massiividega sooritab täpselt 10 võrdlust iga positsiooni kohta stringis. Tüüpilise 5-10 numbriga stringi puhul tähendab see 50-100 operatsiooni; täitmisaega mõõdetakse mikrosekundites. Võrdluseks, lähenemine preg_replace_callback() kasutamisega regulaaravaldisega lisab üldkulu mustri kompileerimisele ja callback'i väljakutsumisele iga vaste jaoks. Erinevus on väikeste stringide puhul märkamatu, kuid str_replace() võidab suurte mahtude korral.

Lähenemise peamine piirang on see, et see asendab märke, mitte numbri semantikat. Kui vajad aritmeetikat devanaagari numbritega (liitmine, korrutamine), ei tuvasta PHP devanaagari sümboleid numbritena. Teisenda alati enne matemaatilisi tehteid araabia numbriteks ja pärast tagasi. See ei ole meetodi viga, vaid kirjasüsteemide ja numbriliste andmetüüpide erinevuse tagajärg.

Veel üks nüanss: meetod eeldab üks-ühele vastavust "üks märk, üks number". Kirjasüsteemide puhul, kus numbreid kirjutatakse liit-ligatuuridega (nagu mõnes ajaloolises süsteemis), lihtne asendusmeetod ei tööta. Kuid kõigi kaasaegsete India kirjade (devanaagari, bengali, gurmukhi, gudžarati, oria, tamili, telugu, kannada, malajalami) ja ka idapoolsete araabia numbrite puhul on vastavus rangelt 1:1 ja meetod töötab veatult.

Mida tootmisse juurutada: PHP, JavaScript või mõlemad?

PHP lahendus on juhtudeks, kui numbrid tuleb renderdada sihtmärgi sümbolisüsteemis serveris enne HTML-i saatmist. See on SEO jaoks õige: otsingumootor näeb sisu kohe sihtlokaadis, mitte araabia numbritena, mis seejärel skriptiga asendatakse. WooCommerce'i poe puhul tähendab see, et kataloogi ja tootelehe hinnad indekseeritakse devanaagari numbritega, mis mõjutab positiivselt edetabelit nepali ja hindi segmentides.

JavaScript variant on dünaamiliseks suhtluseks: sisestusväli kohese eelvaatega, keelevahetus ilma lehe uuesti laadimiseta, vormiandmete teisendus enne saatmist. See on samuti hädavajalik üheleheliste rakenduste (SPA) jaoks, kus server tagastab JSON-i araabia numbritega ja esikülg renderdab need kasutaja lokaadis.

Praktikas töötab kombinatsioon hästi: PHP renderdab lehe lokaliseeritud numbritega indekseerimiseks, samas kui JavaScript käsitleb kasutaja sisendit ja teisendab jooksvalt edasi-tagasi. Mõlemad koodinäited, ilma väliste sõltuvusteta, on kokku vähem kui 40 rida ja need lahendavad ülesande täielikult iga kirjasüsteemi jaoks, millel on oma numbrilised märgid.

Enne tootmisse juurutamist testi kolme stsenaariumi: otsene funktsiooni väljakutse numbriga, segasisuga string (numbrid pluss tekst) ja vastupidine teisendus. Veendu, et araabia numbrid jõuavad alati serverisse ja liides näitab kasutajale süsteemi, mis vastab nende keeleootustele. Viis minutit testimist säästab tunde silumist reaalse liikluse peal.

Kopeeri mõlemad koodinäited oma projekti, asenda vajalikud sümbolid Unicode'i tabelist oma kirjasüsteemi jaoks ja ülesanne on lahendatud. Kõik vajalik on juba keelde sisse ehitatud.