
🔢 Number translation with PHP and JavaScript: Arabic numerals to Devanagari and back
A user fills out a form on a website, and the numbers turn into unreadable characters. This is a familiar situation for anyone working with multilingual projects: the Nepali version of an online store shows prices in अक्षर, and the contact form fails validation because of "incorrect" digits.
The problem is that different languages use different numeral systems. English and Russian use Arabic numerals (0-9). Hindi, Nepali, and Marathi use Devanagari symbols (०-९). PHP and JavaScript do not switch between them out of the box. Yet the task can be solved without a single external library, using only built-in string functions. No dependencies to install, no third-party APIs.
Below are two ready-to-use code snippets that solve this problem in 5 minutes. No frameworks, no Composer packages, no npm dependencies, just plain PHP and vanilla JavaScript. Copy them, substitute your symbols, and it works.
💡 Quick overview:
- Copy the PHP function into your theme's functions.php or via the Code Snippets plugin; it converts Arabic numerals to Devanagari and back
- For the frontend, use the ready-made JavaScript code with dictionary objects for on-the-fly conversion right in the input field
- The replacement uses a glyph correspondence table rather than math, making the method universal for any writing system
- Test it: pass 1234 and get १२३४, and vice versa; both directions work symmetrically
How numeral systems work in different languages
Most websites work with Arabic numerals: 0 1 2 3 4 5 6 7 8 9. Historically this system came from India but became widespread through the Arab world, hence the name.
Alternative sets exist in dozens of writing systems. Devanagari (Hindi, Nepali, Marathi) uses its own series: ० १ २ ३ ४ ५ ६ ७ ८ ९. Eastern Arabic numerals (Arabic, Persian, Urdu) use a different set: ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩. Bengali, Thai, and Khmer each have their own glyphs and their own Unicode ranges. There are more than twenty such systems in total.
But the numeric value remains the same. 5, ५, and ٥ are all the same number "five," just written with different symbols. Therefore, translation between systems is glyph replacement using a correspondence table, not mathematical conversion. There is nothing to recalculate; you just need to know the correct symbol pairs.
This is exactly the principle behind the code below.
Step 1: Converting numbers with PHP

The PHP approach is as simple as it gets: the str_replace() function takes two arrays, what to find and what to replace with. The string is processed in a single pass, and all matches are replaced.
Add this code to your child theme's functions.php or via the Code Snippets plugin. The function accepts a number or a string containing digits and returns the result with Devanagari symbols.
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 */ 8 function 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 */ 16 echo convert_to_devanagari(2026); 17 // Output: २०२६ 18 ?>
What happens here: str_replace() iterates through the $english array, and for each element (for example, "2") substitutes the corresponding element from $devanagari ("२"). Casting to (string) ensures the function works with both numbers and strings.
Reverse conversion, from Devanagari to Arabic numerals, is done by swapping the arrays:
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 */ 8 function 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 */ 16 echo convert_from_devanagari('२०२६'); 17 // Output: 2026 18 ?>
The arrays are the same; only the argument order changes. The first array now contains Devanagari symbols (what we search for), the second contains Arabic numerals (what we replace with).
Where to use. The function is useful anywhere in the theme where numbers are displayed: product prices in WooCommerce, dates in blog posts, page numbering. Wrap the call wherever you need digit localization for a specific audience.
Handling edge cases in PHP
The convert_to_devanagari() function accepts string|int, but in practice the input can be anything. What happens if you pass null, an empty string, or a string with no digits? (string) null returns an empty string, and str_replace() with an empty string also returns empty without errors. A string without digits (for example, "Hello") returns unchanged since the replacement finds no matches.
If the number contains separators (commas for thousands, a period for decimals), they remain in place; only the digits themselves are replaced. For floating-point numbers this behavior is correct, but if number formatting matters and separators should change according to the locale, add separate processing via number_format() before conversion.
For very long numbers (for example, 20-digit identifiers) the approach works without changes: str_replace() processes strings of any length, limited only by available PHP memory. Devanagari characters take 3 bytes each in UTF-8, so the resulting string will be longer than the original in bytes. For character counting, use mb_strlen(), not strlen().
Step 2: Converting numbers with JavaScript
On the frontend, the same logic is implemented using dictionary objects and the String.replace() method with a regular expression. This is convenient for dynamic interfaces: the user enters a number in a field, and the script instantly shows the Devanagari equivalent.
Place this code in a separate .js file in your theme or via wp_add_inline_script in functions.php. No dependencies, plain ES5, works even in old browsers.
1 /** 2 * Dictionaries for translating between Arabic numerals and Devanagari. 3 */ 4 var englishToDevanagari = { 5 '0': '०', '1': '१', '2': '२', '3': '३', '4': '४', 6 '5': '५', '6': '६', '7': '७', '8': '८', '9': '९' 7 }; 8 9 var 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 */ 19 function 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 */ 30 function fromDevanagari(input) { 31 return input.replace(/[०-९]/g, function(match) { 32 return devanagariToEnglish[match]; 33 }); 34 } 35 36 // Examples: 37 console.log(toDevanagari(9857)); // ९८५७ 38 console.log(fromDevanagari('१२३४')); // 1234
The key point is the regular expression /[0-9]/g. The g (global) flag makes replace() process every digit in the string, not just the first one. The anonymous callback function receives the matched character and returns its equivalent from the dictionary.
For Devanagari digits, the range [०-९] is used; in Unicode these characters are sequential, so the regex works correctly.
Where to use. Live input in forms (on-the-fly conversion while typing), displaying prices and dates in localized versions of the site, reverse conversion before submitting the form to the server so that Arabic numerals always go to the database.
Practical example: contact form with on-the-fly conversion
Let us combine both approaches into a working setup. Suppose the Nepali version of a site has an order form where the user enters an amount in Devanagari. The task: show the entered number in both systems for verification and send Arabic numerals to the server.
The form markup contains an <input> and a preview block. On each keystroke in the field, the input event handler fires, calling toDevanagari() and displaying the result in an adjacent <span>. When the form is submitted, fromDevanagari() fires, and the POST request body sent to the server contains Arabic numerals. The PHP server-side code receives the number in standard format and works with it as usual, without additional conversion.
This same pattern applies to price fields, dates, phone numbers, and any other fields where the user expects to see their native numeral system while the system needs to store a unified format. Conversion takes microseconds and does not affect interface responsiveness.
See also: video on numeral systems in programming
For a broader look at the topic of how numeral systems work in code and how to convert between them in JavaScript, watch this breakdown by Techno Geek. It covers binary, octal, and decimal systems with a ready-made project.
⁉️🤔 Frequently asked questions
Can this same method convert digits to Arabic (Eastern Arabic symbols)?
Yes. Replace the Devanagari array with Eastern Arabic symbols:
array("٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"). The logic is the same:str_replace()in PHP and a dictionary with regex in JS. It adapts just as easily to Bengali, Thai, Khmer, and any other writing system with its own numeric glyphs.
Is it safe to use str_replace() for multibyte strings in PHP?
Yes,
str_replace()works correctly with UTF-8 and multibyte characters, unlikestrpos()orsubstr()which need mbstring equivalents. Devanagari symbols (२,३) take 3 bytes each in UTF-8, butstr_replace()handles them in a byte-safe manner because it searches for exact binary sequence matches. There will be no problems.
What if the string contains a mix of Arabic numerals and Devanagari symbols?
Both functions process only their respective ranges. If
convert_to_devanagari()receives the string"Price: 500 रुपय", the numeral500becomes५००while the text remains untouched. The reverse functionconvert_from_devanagari()affects only Devanagari digits. Mixed input is handled correctly automatically.
How can I apply conversion to all numbers on a WordPress page without editing each template?
Use the JavaScript approach from step 2 and run a DOM node traversal on page load. Find all text nodes containing digits (via
TreeWalkeror recursivechildNodestraversal) and applytoDevanagari()to their content. For the PHP approach on the server side, use a filter onthe_contentorgettextif numbers are embedded in translations.
Where can I find character tables for other writing systems?
The authoritative source is the Unicode Consortium. For Devanagari digits, this is the range U+0966-U+096F. Eastern Arabic is U+0660-U+0669. Bengali is U+09E6-U+09EF. Simply copy the characters from the table and substitute them into the arrays; the code does not need to change.
Performance and limitations of the approach
str_replace() with arrays of 10 elements performs exactly 10 comparisons for each position in the string. For a typical string with 5-10 digits, this means 50-100 operations; execution time is measured in microseconds. By comparison, the approach using preg_replace_callback() with a regular expression adds overhead for pattern compilation and callback invocation for each match. The difference is imperceptible for small strings, but str_replace() wins on large volumes.
The main limitation of the approach is that it replaces glyphs, not the semantics of the number. If you need arithmetic on Devanagari numbers (addition, multiplication), Devanagari symbols will not be recognized as numbers by PHP. Always convert to Arabic numerals before mathematical operations and convert back afterward. This is not a flaw in the method but a consequence of the difference between writing systems and numeric data types.
Another nuance: the method assumes a one-to-one correspondence of "one glyph, one digit." For writing systems where numbers are written with composite ligatures (as in some historical systems), the simple replacement approach will not work. But for all modern Indian scripts (Devanagari, Bengali, Gurmukhi, Gujarati, Odia, Tamil, Telugu, Kannada, Malayalam), as well as for Eastern Arabic numerals, the correspondence is strictly 1 to 1, and the method works flawlessly.
What to deploy to production: PHP, JavaScript, or both?
The PHP solution is for cases when numbers must be rendered in the target symbol system on the server before the HTML is sent. This is correct for SEO: the search engine sees the content immediately in the target locale, not Arabic numerals that are then replaced by a script. For a WooCommerce store, this means catalog and product page prices are indexed with Devanagari digits, which positively affects ranking in the Nepali and Hindi segments.
The JavaScript variant is for dynamic interaction: an input field with instant preview, language switching without page reload, form data conversion before submission. It is also indispensable for single-page applications (SPA) where the server returns JSON with Arabic numerals and the frontend renders them in the user's locale.
In practice, a combination works well: PHP renders the page with localized digits for indexing, while JavaScript handles user input and converts back and forth on the fly. Both code snippets, without external dependencies, are fewer than 40 lines combined, and they completely solve the task for any writing system with its own numeric glyphs.
Before deploying to production, test three scenarios: a direct function call with a number, a string with mixed content (digits plus text), and reverse conversion. Make sure Arabic numerals always reach the server, and the interface shows the user the system that matches their language expectations. Five minutes of testing saves hours of debugging on live traffic.
Copy both code snippets into your project, substitute the needed symbols from the Unicode table for your writing system, and the task is done. Everything you need is already built into the language.



