如何使用JavaScript将字符串中的波斯语和阿拉伯数字转换为英语?

Ali*_*.MD 13 javascript arabic persian

如何通过简单的功能将波斯语/阿拉伯数字转换为英文数字?

arabicNumbers = ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]
persianNumbers = ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]
Run Code Online (Sandbox Code Playgroud)

它是相同的模式,但代码页是不同的.

yuk*_*say 51

英语、阿拉伯语和波斯语数字之间所有 6 种可能的翻译的Oneliner

const e2p = s => s.replace(/\d/g, d => '??????????'[d])
const e2a = s => s.replace(/\d/g, d => '??????????'[d])

const p2e = s => s.replace(/[?-?]/g, d => '??????????'.indexOf(d))
const a2e = s => s.replace(/[?-?]/g, d => '??????????'.indexOf(d))

const p2a = s => s.replace(/[?-?]/g, d => '??????????'['??????????'.indexOf(d)])
const a2p = s => s.replace(/[?-?]/g, d => '??????????'['??????????'.indexOf(d)])

e2p("asdf1234") // asdf????
e2a("asdf1234") // asdf????
p2e("asdf????") // asdf1234
a2e("asdf????") // asdf1234
p2a("asdf????") // asdf????
a2p("asdf????") // asdf????
Run Code Online (Sandbox Code Playgroud)

说明:

  • (s => f(s))(x) 是一个立即执行的 lambda 函数,将等于 f(x)
  • s.replace(pattern, function)在 s 中查找模式的匹配项,对于每个匹配项 m 它将替换function(m)字符串中的m 。
  • /\d/g是正则表达式模式,\d在英语中表示数字,g表示全局。如果你没有指定g它只会匹配第一次出现,否则它会匹配所有出现。
  • 在这种情况下,对于d字符串中的每个英文数字,该数字将被替换为'??????????'[d]so,3 将被替换为该 list( '??????????') 中的第三个索引,即“?”
  • /[?-?]/g是波斯数字的等效正则表达式,这次我们不能使用相同的方法,在我们利用 javascript 是动态类型并且 d 自动从字符串(正则表达式匹配)转换为数字(数组索引)这一事实之前(您可以'1234'['1']在与 javascript 相同的 javascript 中执行'1234'[1]
  • 但这次我们不能这样做,因为'1234'['?']无效。所以我们在这里使用一个技巧并使用indexOfwhich 是一个函数,它告诉我们数组中元素的索引(这里是字符串中的一个字符)所以,'??????????'.indexOf(?)会给我们3因为'?'是字符串中的第三个索引'??????????'


Ali*_*.MD 20

使用此简单函数转换您的字符串

var
persianNumbers = [/?/g, /?/g, /?/g, /?/g, /?/g, /?/g, /?/g, /?/g, /?/g, /?/g],
arabicNumbers  = [/?/g, /?/g, /?/g, /?/g, /?/g, /?/g, /?/g, /?/g, /?/g, /?/g],
fixNumbers = function (str)
{
  if(typeof str === 'string')
  {
    for(var i=0; i<10; i++)
    {
      str = str.replace(persianNumbers[i], i).replace(arabicNumbers[i], i);
    }
  }
  return str;
};
Run Code Online (Sandbox Code Playgroud)

请注意,在此代码中,波斯数字代码页与阿拉伯数字不同.

var mystr = 'Sample text ????? and ????';
mystr = fixNumbers(mystr);
Run Code Online (Sandbox Code Playgroud)

Refrence


MMM*_*ION 20

可以支持波斯语/阿拉伯数字(Unicode 数字字符)的最高性能(快速且准确)的函数是:

\n

\r\n
\r\n
function toEnDigit(s) {\n    return s.replace(/[\\u0660-\\u0669\\u06f0-\\u06f9]/g,    // Detect all Persian/Arabic Digit in range of their Unicode with a global RegEx character set\n        function(a) { return a.charCodeAt(0) & 0xf }     // Remove the Unicode base(2) range that not match\n    )\n}\n\nsample=\'English: 0123456789 - Persian: \xdb\xb0\xdb\xb1\xdb\xb2\xdb\xb3\xdb\xb4\xdb\xb5\xdb\xb6\xdb\xb7\xdb\xb8\xdb\xb9 - Arabic: \xd9\xa0\xd9\xa1\xd9\xa2\xd9\xa3\xd9\xa4\xd9\xa5\xd9\xa6\xd9\xa7\xd9\xa8\xd9\xa9\';\n     // English: 0123456789 - Persian: 0123456789 - Arabic: 0123456789\n\nconsole.log( toEnDigit(sample) );
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

它是如何工作的

\n

首先,通过在阿拉伯数字 Unicode波斯数字 Unicode范围内使用Replace() + RegEx 字符集,它将检测与其匹配的字符串中的任何字符。 U+0660 - U+0669 = \xd9\xa0 ... \xdb\xb9 U+06F0 - U+06F9 = \xdb\xb0 ... \xdb\xb9

\n

然后,由于基本拉丁数字(ASCII)在 Unicode 中具有相同的结尾,因此如果我们消除它们在基数上的差异,则结尾可以相同。\n为此,我们可以通过使用charCodeAt()在它们的字符代码之间使用按位与 (&)运算来保留相同的部分。U+0030 - U+0039=0-9

\n

解释:

\n
// x86 (Base 10) --> Binary (Base 2)\n\n\'\xd9\xa4\'.charCodeAt(0);   // 1636 (Base 10)\n\'\xdb\xb4\'.charCodeAt(0);   // 1780 (Base 10)\n\n(1636).toString(2);  // 0000000000000000000001100110 0100 (Base 2)\n(1780).toString(2);  // 0000000000000000000001101111 0100 (Base 2)\n(4).toString(2);     // 0000000000000000000000000000 0100 (Base 2)\n\n// We need a         // 0000000000000000000000000000 1111 (Base 2)\n// To And it, for keeping just the 1\'s\n// 0xf = 15\n(15).toString(2);    // 0000000000000000000000000000 1111 (Base 2)\n\n// So\n(\n1780                 // 0000000000000000000001101111 0100 (Base 2)\n&                    // AND (Operation)\n15                   // 0000000000000000000000000000 1111 (Base 2)\n)\n==\n4                    // 0000000000000000000000000000 0100 (Base 2)  \n// ---> true       \n\n// Also              (1636 & 15) == 4    <--- true\n
Run Code Online (Sandbox Code Playgroud)\n
缩小版本(所有浏览器):
\n
function toEnDigit(s){return s.replace(/[\\u0660-\\u0669\\u06f0-\\u06f9]/g,function(a){return a.charCodeAt(0)&15})}\n
Run Code Online (Sandbox Code Playgroud)\n
OneLiner(现代浏览器)
\n
const toEnDigit=s=>s.replace(/[\xd9\xa0-\xd9\xa9\xdb\xb0-\xdb\xb9]/g,a=>a.charCodeAt(0)&15);\n
Run Code Online (Sandbox Code Playgroud)\n


Hex*_*boY 15

这是一个简单的方法:

function toEnglishDigits(str) {

    // convert persian digits [??????????]
    var e = '?'.charCodeAt(0);
    str = str.replace(/[?-?]/g, function(t) {
        return t.charCodeAt(0) - e;
    });

    // convert arabic indic digits [??????????]
    e = '?'.charCodeAt(0);
    str = str.replace(/[?-?]/g, function(t) {
        return t.charCodeAt(0) - e;
    });
    return str;
}
Run Code Online (Sandbox Code Playgroud)

一个例子:

console.log(toEnglishDigits("abc[0123456789][??????????][??????????]"));
// expected result => abc[0123456789][0123456789][0123456789]
Run Code Online (Sandbox Code Playgroud)


小智 13

最好的方法是返回数组中数字的索引:

String.prototype.toEnglishDigits = function () {
    return this.replace(/[?-?]/g, function (chr) {
        var persian = ['?', '?', '?', '?', '?', '?', '?', '?', '?', '?'];
        return persian.indexOf(chr);
    });
};
Run Code Online (Sandbox Code Playgroud)


Ahm*_*mad 8

简短而轻松!

"??????????".replace(/([?-?])/g, function(token) { return String.fromCharCode(token.charCodeAt(0) - 1728); });
Run Code Online (Sandbox Code Playgroud)

或者以更现代的方式

"??????????".replace(/([?-?])/g, token => String.fromCharCode(token.charCodeAt(0) - 1728));
Run Code Online (Sandbox Code Playgroud)


Moh*_*fei 8

如果字符串可能包含两个“阿拉伯语”和“波斯”的数字,然后一个单行的“替换”如下可以做的工作。

阿拉伯数字和波斯数字将转换为英语等效数字。其他文字保持不变。

Num= "?????any????32??";     // Output should be "33665any55453200"

Num = Num.replace(/[?-?]/g, d => "??????????".indexOf(d)).replace(/[?-?]/g, d => "??????????".indexOf(d));

console.log(Num);
Run Code Online (Sandbox Code Playgroud)

  • 这是[yukashima](/sf/answers/4070991081/)答案方法的混合,它很聪明。但为了更紧凑和更快,我建议像这样:``Num.replace(/[٠-٩0-9]/g, d =&gt; d="٠١٢٣٤٥٦٧٨٩0123456789".indexOf(d) % 10);``您可以在此处检查方法性能:https://jsben.ch/IaDxH (2认同)

Ed *_*lot 6

您可以执行类似的操作,使用字符串中数字的索引来进行转换:

\n\n

\r\n
\r\n
// Returns -1 if `fromNum` is not a numeric character\r\nfunction convertNumber(fromNum) {\r\n    var persianNums = \'\xdb\xb0\xd9\xa1\xdb\xb2\xdb\xb3\xdb\xb4\xdb\xb5\xdb\xb6\xdb\xb7\xdb\xb8\xdb\xb9\';\r\n    return persianNums.indexOf(fromNum);\r\n}\r\n\r\nvar testNum = \'\xdb\xb4\';\r\nalert("number is: " + convertNumber(testNum));
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n\n

或者使用这样的对象进行映射:

\n\n

\r\n
\r\n
// Returns -1 if `fromNum` is not a numeric character\r\nfunction convertNumber(fromNum) {\r\n    var result;\r\n    var arabicMap = {\r\n        \'\xd9\xa9\': 9,\r\n        \'\xd9\xa8\': 8,\r\n        \'\xd9\xa7\': 7,\r\n        \'\xd9\xa6\': 6,\r\n        \'\xd9\xa5\': 5,\r\n        \'\xd9\xa4\': 4,\r\n        \'\xd9\xa3\': 3,\r\n        \'\xd9\xa2\': 2,\r\n        \'\xd9\xa1\': 1,\r\n        \'\xd9\xa0\': 0\r\n    };\r\n    result = arabicMap[fromNum];\r\n    if (result === undefined) {\r\n        result = -1;\r\n    }\r\n    return result;\r\n}\r\n\r\nvar testNum = \'\xd9\xa4\';\r\nalert("number is: " + convertNumber(testNum));
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n


vsy*_*ync 6

将任何波斯阿拉伯(或混合)数字转换为“英语”数字(印度-阿拉伯数字

var transformNumbers = (function(){
    var numerals = {
        persian : ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?"],
        arabic  : ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]
    };

    function fromEnglish(str, lang){
        var i, len = str.length, result = "";

        for( i = 0; i < len; i++ )
            result += numerals[lang][str[i]]; 

        return result;
    }

    return {
        toNormal : function(str){
            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;
        },

        toPersian : function(str, lang){
            return fromEnglish(str, "persian");
        },

        toArabic : function(str){
            return fromEnglish(str, "arabic");
        }
    }
})();

//////// ON INPUT EVENT //////////////

document.querySelectorAll('input')[0].addEventListener('input', onInput_Normal);
document.querySelectorAll('input')[1].addEventListener('input', onInput_Arabic);

function onInput_Arabic(){
   var _n = transformNumbers.toArabic(this.value);
   console.clear();
   console.log( _n )
}

function onInput_Normal(){
   var _n = transformNumbers.toNormal(this.value);
   console.clear();
   console.log( _n )
}
Run Code Online (Sandbox Code Playgroud)
input{ width:90%; margin-bottom:1em; font-size:1.5em; padding:5px; }
Run Code Online (Sandbox Code Playgroud)
<input placeholder="write in Arabic numerals">

<input placeholder="write in normal numerals">
Run Code Online (Sandbox Code Playgroud)


sha*_*ank 5

function toEnglishDigits(str) {\n  const persianNumbers = ["\xdb\xb1", "\xdb\xb2", "\xdb\xb3", "\xdb\xb4", "\xdb\xb5", "\xdb\xb6", "\xdb\xb7", "\xdb\xb8", "\xdb\xb9", "\xdb\xb0"]\n  const arabicNumbers = ["\xd9\xa1", "\xd9\xa2", "\xd9\xa3", "\xd9\xa4", "\xd9\xa5", "\xd9\xa6", "\xd9\xa7", "\xd9\xa8", "\xd9\xa9", "\xd9\xa0"]\n  const englishNumbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]\n  \n  return str.split("").map(c => englishNumbers[persianNumbers.indexOf(c)] ||\n      englishNumbers[arabicNumbers.indexOf(c)] || c).join("")\n}\n\ntoEnglishDigits("\xdb\xb6\xd9\xa6\xdb\xb5any\xd9\xa532") // "665any532"\n
Run Code Online (Sandbox Code Playgroud)\n