Skip to content

Tutto per WordPress, lo sviluppo web — e non solo

🔢 Traduzione di numeri con PHP e JavaScript: numeri arabi in devanagari e viceversa

🔢 Traduzione di numeri con PHP e JavaScript: numeri arabi in devanagari e viceversa

Un utente compila un modulo su un sito web e i numeri diventano caratteri illeggibili. È una situazione familiare per chiunque lavori con progetti multilingue: la versione nepalese di un negozio online mostra i prezzi in अक्षर e il modulo di contatto fallisce la validazione a causa di cifre "errate".

Il problema è che lingue diverse usano sistemi di numerazione diversi. Inglese e russo usano i numeri arabi (0-9). Hindi, nepalese e marathi usano i simboli devanagari (०-९). PHP e JavaScript non passano automaticamente dall'uno all'altro. Eppure il problema si può risolvere senza una sola libreria esterna, usando solo le funzioni di stringa integrate. Nessuna dipendenza da installare, nessuna API di terze parti.

Ecco due snippet di codice pronti all'uso che risolvono il problema in 5 minuti. Niente framework, niente pacchetti Composer, niente dipendenze npm, solo PHP puro e JavaScript vanilla. Copiateli, sostituite i vostri simboli e funziona.

💡 Panoramica rapida:

  • Copiate la funzione PHP nel file functions.php del vostro tema o tramite il plugin Code Snippets; converte i numeri arabi in devanagari e viceversa
  • Per il frontend, usate il codice JavaScript già pronto con oggetti dizionario per la conversione al volo direttamente nel campo di input
  • La sostituzione usa una tabella di corrispondenza dei glifi anziché la matematica, rendendo il metodo universale per qualsiasi sistema di scrittura
  • Testatelo: passate 1234 e ottenete १२३४, e viceversa; entrambe le direzioni funzionano simmetricamente

Come funzionano i sistemi di numerazione nelle diverse lingue

La maggior parte dei siti web lavora con i numeri arabi: 0 1 2 3 4 5 6 7 8 9. Storicamente questo sistema proviene dall'India ma si è diffuso attraverso il mondo arabo, da cui il nome.

Esistono set alternativi in dozzine di sistemi di scrittura. Il devanagari (hindi, nepalese, marathi) usa una propria serie: ० १ २ ३ ४ ५ ६ ७ ८ ९. I numeri arabi orientali (arabo, persiano, urdu) usano un set diverso: ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩. Bengalese, thailandese e khmer hanno ciascuno i propri glifi e i propri intervalli Unicode. In totale esistono più di venti sistemi di questo tipo.

Ma il valore numerico rimane lo stesso. 5, e ٥ sono tutti lo stesso numero "cinque", solo scritto con simboli diversi. Pertanto, la traduzione tra sistemi è una sostituzione di glifi tramite una tabella di corrispondenza, non una conversione matematica. Non c'è nulla da ricalcolare; basta conoscere le coppie di simboli corrette.

È esattamente questo il principio alla base del codice seguente.

Passo 1: Convertire i numeri con PHP

Programmatore che lavora al laptop con un editor di codice aperto

L'approccio PHP è il più semplice possibile: la funzione str_replace() prende due array, cosa cercare e con cosa sostituire. La stringa viene elaborata in un unico passaggio e tutte le corrispondenze vengono sostituite.

Aggiungete questo codice al file functions.php del vostro tema child o tramite il plugin Code Snippets. La funzione accetta un numero o una stringa contenente cifre e restituisce il risultato con i simboli devanagari.

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

Cosa succede qui: str_replace() itera attraverso l'array $english e per ogni elemento (ad esempio, "2") sostituisce l'elemento corrispondente da $devanagari ("२"). Il cast a (string) assicura che la funzione funzioni sia con numeri che con stringhe.

La conversione inversa, da devanagari a numeri arabi, si ottiene scambiando gli array:

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

Gli array sono gli stessi; cambia solo l'ordine degli argomenti. Il primo array ora contiene i simboli devanagari (ciò che cerchiamo), il secondo contiene i numeri arabi (con cosa li sostituiamo).

Dove usarla. La funzione è utile ovunque nel tema vengano visualizzati numeri: prezzi dei prodotti in WooCommerce, date negli articoli del blog, numerazione delle pagine. Inserite la chiamata ovunque abbiate bisogno della localizzazione delle cifre per un pubblico specifico.

Gestire i casi limite in PHP

La funzione convert_to_devanagari() accetta string|int, ma in pratica l'input può essere qualsiasi cosa. Cosa succede se passate null, una stringa vuota o una stringa senza cifre? (string) null restituisce una stringa vuota, e str_replace() con una stringa vuota restituisce anch'esso vuoto senza errori. Una stringa senza cifre (ad esempio, "Hello") viene restituita invariata poiché la sostituzione non trova corrispondenze.

Se il numero contiene separatori (virgole per le migliaia, un punto per i decimali), questi rimangono al loro posto; solo le cifre stesse vengono sostituite. Per i numeri a virgola mobile questo comportamento è corretto, ma se la formattazione del numero è importante e i separatori dovrebbero cambiare in base alla lingua, aggiungete un'elaborazione separata tramite number_format() prima della conversione.

Per numeri molto lunghi (ad esempio, identificatori a 20 cifre) l'approccio funziona senza modifiche: str_replace() elabora stringhe di qualsiasi lunghezza, limitato solo dalla memoria PHP disponibile. I caratteri devanagari occupano 3 byte ciascuno in UTF-8, quindi la stringa risultante sarà più lunga dell'originale in byte. Per il conteggio dei caratteri, usate mb_strlen(), non strlen().

Passo 2: Convertire i numeri con JavaScript

Sul frontend, la stessa logica è implementata usando oggetti dizionario e il metodo String.replace() con una espressione regolare. Questo è comodo per le interfacce dinamiche: l'utente inserisce un numero in un campo e lo script mostra istantaneamente l'equivalente devanagari.

Inserite questo codice in un file .js separato nel vostro tema o tramite wp_add_inline_script in functions.php. Nessuna dipendenza, semplice ES5, funziona anche nei browser più vecchi.

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

Il punto chiave è l'espressione regolare /[0-9]/g. Il flag g (global) fa sì che replace() elabori ogni cifra nella stringa, non solo la prima. La funzione di callback anonima riceve il carattere corrispondente e restituisce il suo equivalente dal dizionario.

Per le cifre devanagari, si usa l'intervallo [०-९]; in Unicode questi caratteri sono sequenziali, quindi la regex funziona correttamente.

Dove usarlo. Input in tempo reale nei moduli (conversione al volo durante la digitazione), visualizzazione di prezzi e date nelle versioni localizzate del sito, conversione inversa prima di inviare il modulo al server in modo che al database arrivino sempre numeri arabi.

Esempio pratico: modulo di contatto con conversione al volo

Combiniamo entrambi gli approcci in una configurazione funzionante. Supponiamo che la versione nepalese di un sito abbia un modulo d'ordine in cui l'utente inserisce un importo in devanagari. Il compito: mostrare il numero inserito in entrambi i sistemi per verifica e inviare numeri arabi al server.

Il markup del modulo contiene un <input> e un blocco di anteprima. A ogni pressione di tasto nel campo, il gestore di eventi input si attiva, chiama toDevanagari() e mostra il risultato in un <span> adiacente. Quando il modulo viene inviato, fromDevanagari() si attiva e il corpo della richiesta POST inviato al server contiene numeri arabi. Il codice lato server PHP riceve il numero in formato standard e ci lavora come al solito, senza conversioni aggiuntive.

Questo stesso schema si applica ai campi prezzo, alle date, ai numeri di telefono e a qualsiasi altro campo in cui l'utente si aspetta di vedere il proprio sistema di numerazione nativo mentre il sistema deve memorizzare un formato unificato. La conversione richiede microsecondi e non influisce sulla reattività dell'interfaccia.

Vedi anche: video sui sistemi di numerazione nella programmazione

Per uno sguardo più ampio sul tema di come funzionano i sistemi di numerazione nel codice e come convertirli in JavaScript, guardate questa analisi di Techno Geek. Copre i sistemi binario, ottale e decimale con un progetto già pronto.

⁉️🤔 Domande frequenti

Questo stesso metodo può convertire le cifre in arabo (simboli arabi orientali)?

Sì. Sostituite l'array devanagari con i simboli arabi orientali: array("٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"). La logica è la stessa: str_replace() in PHP e un dizionario con regex in JS. Si adatta altrettanto facilmente a bengalese, thailandese, khmer e qualsiasi altro sistema di scrittura con i propri glifi numerici.

È sicuro usare str_replace() per stringhe multibyte in PHP?

Sì, str_replace() funziona correttamente con UTF-8 e caratteri multibyte, a differenza di strpos() o substr() che necessitano di equivalenti mbstring. I simboli devanagari (, ) occupano 3 byte ciascuno in UTF-8, ma str_replace() li gestisce in modo sicuro a livello di byte perché cerca corrispondenze esatte di sequenze binarie. Non ci saranno problemi.

Cosa succede se la stringa contiene un mix di numeri arabi e simboli devanagari?

Entrambe le funzioni elaborano solo i rispettivi intervalli. Se convert_to_devanagari() riceve la stringa "Price: 500 रुपय", il numero 500 diventa ५०० mentre il testo rimane intatto. La funzione inversa convert_from_devanagari() influisce solo sulle cifre devanagari. L'input misto viene gestito correttamente in automatico.

Come posso applicare la conversione a tutti i numeri su una pagina WordPress senza modificare ogni template?

Usate l'approccio JavaScript del passo 2 ed eseguite un attraversamento dei nodi DOM al caricamento della pagina. Trovate tutti i nodi di testo contenenti cifre (tramite TreeWalker o attraversamento ricorsivo di childNodes) e applicate toDevanagari() al loro contenuto. Per l'approccio PHP lato server, usate un filtro su the_content o gettext se i numeri sono incorporati nelle traduzioni.

Dove posso trovare le tabelle dei caratteri per altri sistemi di scrittura?

La fonte autorevole è il Consorzio Unicode. Per le cifre devanagari, questo è l'intervallo U+0966-U+096F. L'arabo orientale è U+0660-U+0669. Il bengalese è U+09E6-U+09EF. Copiate semplicemente i caratteri dalla tabella e sostituiteli negli array; il codice non ha bisogno di essere modificato.

Prestazioni e limiti dell'approccio

str_replace() con array di 10 elementi esegue esattamente 10 confronti per ogni posizione nella stringa. Per una tipica stringa con 5-10 cifre, questo significa 50-100 operazioni; il tempo di esecuzione si misura in microsecondi. A confronto, l'approccio che usa preg_replace_callback() con un'espressione regolare aggiunge un overhead per la compilazione del pattern e l'invocazione del callback per ogni corrispondenza. La differenza è impercettibile per stringhe piccole, ma str_replace() vince su grandi volumi.

Il limite principale dell'approccio è che sostituisce i glifi, non la semantica del numero. Se avete bisogno di fare aritmetica su numeri devanagari (addizione, moltiplicazione), i simboli devanagari non saranno riconosciuti come numeri da PHP. Convertite sempre in numeri arabi prima delle operazioni matematiche e riconvertite dopo. Questo non è un difetto del metodo ma una conseguenza della differenza tra sistemi di scrittura e tipi di dati numerici.

Un'altra sfumatura: il metodo presuppone una corrispondenza uno a uno "un glifo, una cifra". Per i sistemi di scrittura in cui i numeri sono scritti con legature composite (come in alcuni sistemi storici), l'approccio di semplice sostituzione non funzionerà. Ma per tutte le scritture indiane moderne (devanagari, bengalese, gurmukhi, gujarati, odia, tamil, telugu, kannada, malayalam), così come per i numeri arabi orientali, la corrispondenza è strettamente 1 a 1 e il metodo funziona perfettamente.

Cosa mettere in produzione: PHP, JavaScript o entrambi?

La soluzione PHP è per i casi in cui i numeri devono essere renderizzati nel sistema di simboli di destinazione sul server prima che l'HTML venga inviato. Questo è corretto per la SEO: il motore di ricerca vede il contenuto immediatamente nella lingua di destinazione, non numeri arabi che vengono poi sostituiti da uno script. Per un negozio WooCommerce, questo significa che i prezzi del catalogo e delle pagine prodotto sono indicizzati con cifre devanagari, il che influisce positivamente sul posizionamento nei segmenti nepalese e hindi.

La variante JavaScript è per l'interazione dinamica: un campo di input con anteprima istantanea, cambio di lingua senza ricaricare la pagina, conversione dei dati del modulo prima dell'invio. È inoltre indispensabile per le applicazioni a pagina singola (SPA) dove il server restituisce JSON con numeri arabi e il frontend li renderizza nella lingua dell'utente.

In pratica, una combinazione funziona bene: PHP renderizza la pagina con cifre localizzate per l'indicizzazione, mentre JavaScript gestisce l'input dell'utente e converte avanti e indietro al volo. Entrambi gli snippet di codice, senza dipendenze esterne, sono meno di 40 righe in totale e risolvono completamente il compito per qualsiasi sistema di scrittura con i propri glifi numerici.

Prima di mettere in produzione, testate tre scenari: una chiamata diretta alla funzione con un numero, una stringa con contenuto misto (cifre più testo) e la conversione inversa. Assicuratevi che i numeri arabi arrivino sempre al server e che l'interfaccia mostri all'utente il sistema che corrisponde alle sue aspettative linguistiche. Cinque minuti di test fanno risparmiare ore di debug sul traffico live.

Copiate entrambi gli snippet di codice nel vostro progetto, sostituite i simboli necessari dalla tabella Unicode per il vostro sistema di scrittura e il compito è fatto. Tutto ciò che vi serve è già integrato nel linguaggio.