skip to Main Content

following all qa about converting digits in javascript in Stackoverflow. However, I had a problem/ question

method one


        // Convert Persian and Arabic digits to English using the new function
        var convertedValue = convertDigitsToEnglish(currentPhoneValue);

    // Function to convert Persian and Arabic digits to English digits
    function convertDigitsToEnglish(value) {
        var persianDigits = '۰۱۲۳۴۵۶۷۸۹';
        var arabicDigits = '٠١٢٣٤٥٦٧٨٩';
        var englishDigits = '0123456789';

        for (var i = 0; i < 10; i++) {
            value = value.replace(new RegExp(persianDigits[i], 'g'), englishDigits[i]);
            value = value.replace(new RegExp(arabicDigits[i], 'g'), englishDigits[i]);
        }

        return value;
    }

enter image description here

method two


        // Convert Persian and Arabic digits to English
        var convertedValue = convert_number.toNormal(phoneField.val());

var convert_number = (function () {
    var numerals = {
        persian: ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹"],
        arabic: ["٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"]
    };

    return {
        toNormal: function (str) {
            if (!str) {
                return '';
            }
            var num, i, len = str.length, result = "";

            for (i = 0; i < len; i++) {
                num = numerals["persian"].indexOf(str[i]);
                num = num != -1 ? num : numerals["arabic"].indexOf(str[i]);
                if (num == -1) num = str[i];
                result += num;
            }
            return result;
        }
    }
}

enter image description here

in the method one works only for Persian/Farsi digits! and why doesn’t it work correctly at all for the Arabic language?
arabic digits numbers ٤٥٦‍ (four five and six) numbers are not converted to English/Latin numbers. we defined this in the code and it shouldn’t be a problem and it should work correctly, but it doesn’t and these three numbers can’t be converted, and doesn’t accept these numbers!

in method two. both Persian and Arabic languages converted and no problem with this method.

For better explanations for my question so that nothing is missed. Let’s say this is for a mobile number field.
I have also specified elsewhere that a keyboard the person cannot enter any additional characters such as asterisk, plus, minus, etc., other than the numbers 0 to 9.

        // Remove non-numeric characters
        var numericPhoneValue = convertedValue.replace(/[^0-9]/g, '');

In order for the Arabic and Persian numbers not to be recognized as foreign, I converted them to English numbers with this (upper convert function). So that the user can enter numbers with English, Farsi, and Arabic numbers. And it doesn’t matter what language it is in. Converts to English in any digit. Also, prevents the entry of additional characters.

I also used the pattern solution instead of these (convert), but it is ignored by the browser in different situations, and it is also suitable for English only. And it is not suitable for Persian and Arabic.
Was my method correct? Is there a better, shorter and cleaner way? Why the first method does not work correctly for some Arabic numbers? But does the second method work correctly?

2

Answers


  1. I think you can use something like this which will work with both Farsi and Arabic numbers

    function toEnglishDigits(str) {
      const persianNumbers = ["۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹", "۰"]
      const arabicNumbers = ["١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩", "٠"]
      const englishNumbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
    
      return str.split("").map(c => englishNumbers[persianNumbers.indexOf(c)] ||
        englishNumbers[arabicNumbers.indexOf(c)] || c).join("")
    }
    
    console.log(toEnglishDigits("۶٦۵any٥32"))
    Login or Signup to reply.
  2. Assuming all characters have a Unicode value between the different languages you could store them in a single object or Map instance with their decimal counterpart.

    const decimalMap = new Map([
      // Persian
      ["۰", "0"],
      ["۱", "1"],
      ["۲", "3"],
      // ...
    
      // Arabic
      ["٠", "0"],
      // ...
    ]);
    

    With decimalMap defined translating the characters is a simple as checking if they’re present within decimalMap. If a character is not present, keep it as is.

    function toEnglishDigits(string) {
      return Array.from(string, char => decimalMap.get(char) || char).join("");
    }
    

    The above uses Array.from() to split the string into characters (and keep Unicode surrogate pairs intact). We then check the decimalMap for a translation with decimalMap.get(char) if the character is not in the Map instance undefined will be returned. Which in turn causes the OR operator || to return the right hand side of the operator (the original character).

    // build the decimal translation map
    const decimalMap = new Map();
    
    function addDecimals(decimals) {
      const chars = Array.from(decimals);
      chars.forEach((char, index) => decimalMap.set(char, index.toString()));
    }
    
    addDecimals("۰۱۲۳۴۵۶۷۸۹"); // Persian
    addDecimals("٠١٢٣٤٥٦٧٨٩"); // Arabic
    
    // string translation
    function toEnglishDigits(string) {
      return Array.from(string, char => decimalMap.get(char) || char).join("");
    }
    
    // snippet event handlers
    document.forms["convert-digits"].addEventListener("submit", function (event) {
      event.preventDefault();
      this.elements.output.value = toEnglishDigits(this.elements.input.value);
    });
    
    document.getElementById("input-characters").addEventListener("click", function (event) {
      if (event.target.tagName !== "BUTTON") return;
      document.forms["convert-digits"].elements.input.value += event.target.textContent;
    });
    form {
      margin-bottom: 0.5em;
    }
    
    #input-characters label {
      display: inline-block;
      width: 4em;
    }
    
    #input-characters button {
      display: inline-block;
      width: 2em;
    }
    <form id="convert-digits">
      <input name="input" />
      <button>convert</button>
      <input name="output" disabled />
    </form>
    
    <div id="input-characters">
      <div>
        <label>Persian</label>
        <button type="button">۰</button>
        <button type="button">۱</button>
        <button type="button">۲</button>
        <button type="button">۳</button>
        <button type="button">۴</button>
        <button type="button">۵</button>
        <button type="button">۶</button>
        <button type="button">۷</button>
        <button type="button">۸</button>
        <button type="button">۹</button>
      </div>
    
      <div>
        <label>Arabic</label>
        <button type="button">٠</button>
        <button type="button">١</button>
        <button type="button">٢</button>
        <button type="button">٣</button>
        <button type="button">٤</button>
        <button type="button">٥</button>
        <button type="button">٦</button>
        <button type="button">٧</button>
        <button type="button">٨</button>
        <button type="button">٩</button>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search