27

我想将 html 内容中的每个数字都转换为波斯数字,而不会对页面元素产生其他影响。

例如:

<div style='color: #c2c2c2'>
  text number 1
  <span>text number 2</span>
  <div>
    text number 3
    <b>text number 4</b>
    <a href='#page2'>text number 5</a>
  </div>
</div>

转换为:

<div style='color: #c2c2c2'>
  text number ۱
  <span>text number ۲</span>
  <div>
    text number ۳
    <b>text number ۴</b>
    <a href='#page2'>text number ۵</a>
  </div>
</div>
let persian = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹');
let english = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');

谢谢。

4

13 回答 13

32

您可以使用此方法:(http://jsfiddle.net/A4NfG/1/

persian={0:'۰',1:'۱',2:'۲',3:'۳',4:'۴',5:'۵',6:'۶',7:'۷',8:'۸',9:'۹'};
function traverse(el){
    if(el.nodeType==3){
        var list=el.data.match(/[0-9]/g);
        if(list!=null && list.length!=0){
            for(var i=0;i<list.length;i++)
                el.data=el.data.replace(list[i],persian[list[i]]);
        }
    }
    for(var i=0;i<el.childNodes.length;i++){
        traverse(el.childNodes[i]);
    }
}
于 2013-03-06T13:26:32.080 回答
7

有这个findAndReplaceDOMText.js 可以帮助你。它遍历文档中的所有节点(而不是所有元素)并在nodeType参数等于 3 时替换文本,即TEXT_NODE

此示例将替换整个页面中的数字:

function walkNode(node) { 
    if (node.nodeType == 3) {
        // Do your replacement here
        node.data = node.data.replace(/\d/g,convert);
    }
        
    // Also replace text in child nodes
    for (var i = 0; i < node.childNodes.length; i++) {
        walkNode(node.childNodes[i]); 
    }
}
    
walkNode(document.getElementsByTagName('body')[0]);

function convert(a){
    return ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'][a];
}

请参阅此处的JavaScriptString.replace文档

于 2013-03-06T13:05:59.940 回答
5

如果你想通过 a 选择一些元素selector,你可以使用这个简单的代码(JsFiddle):

persian={0:'۰',1:'۱',2:'۲',3:'۳',4:'۴',5:'۵',6:'۶',7:'۷',8:'۸',9:'۹'};
$(".persian-digit").each(function(){
    for(var i=0;i<=9;i++) {
        var re = new RegExp(i,"g");
        $(this).html($(this).html().replace(re,persian[i]));
    }
});

然后使用它:

<span class="persian-digit">This span contains persian digits (0123456789),</span>
<span>and this one contains english digits (0123456789).</span>
于 2015-01-10T13:42:54.623 回答
5

我写了这个简短的代码。

// ES6
const regex = /[۰-۹]/g
let str = '۰۱۲۳۵۴۸۹۰۷۸۹۰۱۲';
let result = str.replace(regex, function (w) {
    return String.fromCharCode(w.charCodeAt(0) - 1728)
  }
)

console.log(result);

于 2016-11-14T22:15:05.490 回答
1

如果您想在特定元素或选择器上使用它,这可能会有所帮助:

var persian = Array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹');
   function replaceDigits(selector) {

      for(i=0;i<10;i++){

         var regex=eval("/"+i+"/g");

         $(selector).html($(selector).html().replace(regex,persian[i]));

      }

   }

replaceDigits(".selected");

为我工作!

于 2014-05-07T11:34:10.427 回答
1
<script>

    function en2fa(num){
        let arr = [];
        persian = {0:'۰',1:'۱',2:'۲',3:'۳',4:'۴',5:'۵',6:'۶',7:'۷',8:'۸',9:'۹'};
        num.split('').map((number,index)=>{
            arr[index] = (persian[number]);
        });
        return arr.join('');
    }

    console.log(en2fa("86598231452"));

</script>

在 codepen 中测试此代码

https://codepen.io/bashirpour/pen/JvgeYy

于 2018-05-27T13:02:01.613 回答
1

您可以使用它Number.toLocaleString()来转换和格式化单个数字。

let myNumberStr = "123456.7890";
let myNumber = Number(myNumberStr); // Convert from string to number
let persian = myNumber.toLocaleString("fa"); // OR "fa-IR" for IRAN

更高级和完整的答案(转换页面中的所有数字)

localizeNumbers(document.getElementsByTagName('body')[0]);

function localizeNumbers(node) { 
    if (node.nodeType == Node.TEXT_NODE) {
        // Use this if target numbers may contain comma as thousands separators
        node.data = node.data.replace(/([,\d]*\.?\d+)/g, localize);
        // Use this if you do not want to treat comma as thousands separator
        // node.data = node.data.replace(/(\d*\.?\d+)/g, localize);
    }
    // Also, replace numbers in child nodes
    node.childNodes.forEach(localizeNumbers);
}

function localize(numberString) {
  // Convert from string to number
  // Use this if target numbers may contain comma as thousands separators
  let number = Number(numberString.replace(/[^\d.]/g, ""));
  // Use this if you do not want to treat comma as thousands separator
  // let number = Number(numberString);

  // Could also have used "fa-IR" for IRAN
  let persian = number.toLocaleString("fa", { maximumFractionDigits: 10 });
  // Could also have used "en-US" for USA
  let english = number.toLocaleString("en", { maximumFractionDigits: 10 });
  // Could also have used "ar" (which seems to use western digits). "EG" is for Egypt
  let arabic = number.toLocaleString("ar-EG", { maximumFractionDigits: 10 });

  console.log(`Persian: ${persian}`);
  console.log(`English: ${english}`);
  console.log(`Arabic: ${arabic}\n`);

  return persian;
}

localizeNumbers(document.getElementsByTagName('body')[0]);

function localizeNumbers(node) { 
  if (node.nodeType == Node.TEXT_NODE) {
    node.data = node.data.replace(/([,\d]*\.?\d+)/g, localize);
  }
  node.childNodes.forEach(localizeNumbers);
}

function localize(numberString) {
  let number = Number(numberString.replace(/[^\d.]/g, ""));
  let persian = number.toLocaleString("fa", { maximumFractionDigits: 10 });
  let english = number.toLocaleString("en", { maximumFractionDigits: 10 });
  let arabic = number.toLocaleString("ar-EG", { maximumFractionDigits: 10 });

  console.log(`Persian: ${persian}`);
  console.log(`English: ${english}`);
  console.log(`Arabic: ${arabic}\n`);

  return persian;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
<script src="script.js" defer></script>
</head>
<body>


  <div style='color: #c2c2c2'>
    text number 1
    <span>text number 2</span>
    <div>
      text number 3
      <b>text number 4</b>
      <a href='#page2'>text number 5</a>
    </div>
  </div>


  1234
  <div>
    1234
    <p>1234</p>
  </div>
  <p>1234</p>
  <p>1,234</p>
  <p>1234.5678</p>
  <p>1,234.5678</p>
  <p>0.1234</p>
  <p>.1234</p>
  <p>abc1234</p>
  <p>abc1,234</p>
  <p>abc1234def</p>
  <p>abc1,234def</p>
  <p>abc 1234def</p>
  <p>abc 1,234def</p>
  <p>abc 1234 def</p>
  <p>abc 1,234 def</p>
  <p>abc1234.567</p>
  <p>abc1,234.567</p>
  <p>abc1234.567def</p>
  <p>abc1,234.567def</p>
  <p>abc 1234.567def</p>
  <p>abc 1,234.567def</p>
  <p>abc 1234.567 def</p>
  <p>abc 1,234.567 def</p>
</body>
</html>

笔记

  1. 该解决方案会将数字视为Number s 而不是String s。如果您未maximumFractionDigits在 的选项对象中指定toLocaleString,则格式化数字可能会被四舍五入。看到这个帖子

  2. useGrouping: false要在格式化数字中省略千位分隔符,请添加toLocaleString. 请参阅MDN Web 文档:Intl.NumberFormat()W3Schools: JavaScript Number toLocaleString()以查看所有其他可用选项。

  3. 该解决方案将使用正确的波斯位分隔符和小数分隔符(称为 momayyez)格式化数字。使用默认浏览器字体和其他一些字体,这两个字符可能看起来类似于拉丁逗号 ( ,),但它们实际上是具有三个不同 Unicode 值的三个不同字符:

    姓名 统一码值 渲染
    拉丁逗号 U+002C ,
    阿拉伯语/波斯语千位分隔符 U+066C Ø
    阿拉伯语/波斯语小数分隔符 U+066B
  4. 该代码假定 HTML 中的所有原始数字都是英文格式(使用逗号作为千位分隔符,使用点作为小数分隔符)。

我在这里使用了Sjoerd 答案的修改版本。感谢他的回答。

有关不同常用数字的列表,请参阅此 Wikipedia 文章。另外,请参阅这篇文章这篇文章。你也可以使用persian.js 库来完成这一切。

于 2021-12-23T21:36:25.403 回答
0

另一种简单的方法:

String.prototype.toEnglishDigits = function () {
     var charCodeZero = '۰'.charCodeAt(0);

     return this.replace(/[0-9]/g, function (w) {
         return String.fromCharCode(parseInt(w) + charCodeZero);
      });
}
于 2018-05-01T19:43:55.380 回答
0

所有的方式都没有信心,因为很多波斯用户,使用阿拉伯语键盘和阿拉伯语字符与波斯数字不同。

最好也替换阿拉伯字符。

例如,这是波斯语中的零字符:۰,这是阿拉伯语中的零字符:٠

如您所见,两者都是相同的,但它们的 Unicode 不一样。如果你在项目中使用波斯语,我推荐你persian.js,它只有 5 KB。

或者如果你不想使用这个库,你可以使用这个代码:

function convertToPersianNumber(value) {
  const arabicNumbers = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
  const persianNumbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
  const englishNumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

  let confidentValue = value;
  for (var i = 0; i < value.length; i++) {
    const inArabicIndex = arabicNumbers.indexOf(value[i]);
    if (inArabicIndex > -1) {
    confidentValue = confidentValue.replace(
      value[i],
      englishNumbers[inArabicIndex]
    );
  }

  const inPersianIndex = persianNumbers.indexOf(value[i]);
  if (inPersianIndex > -1) {
      confidentValue = confidentValue.replace(
        value[i],
        englishNumbers[inPersianIndex]
      );
    }
  }
  return confidentValue;
}
于 2018-11-12T12:39:58.987 回答
0
  try {
    if (!enDigit &&  !enDigit.toString().length)
      return "";

  let enDigitString = typeof enDigit === 'number' ? enDigit.toString() : enDigit;

  var newValue="";
  for (var i=0;i<enDigitString.length;i++)
  {
      var ch=enDigitString.charCodeAt(i);
      if (ch>=48 && ch<=57)
      {
          // european digit range
          var newChar=ch+1728;
          newValue=newValue+String.fromCharCode(newChar);
      }
      else
          newValue=newValue+String.fromCharCode(ch);
  }
  return newValue;

  }catch (e) {
    return "";
  }
于 2018-11-24T13:15:42.750 回答
0

只是更清晰的片段:

function numbersToPersian (el) {
    ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'].forEach((num, index) => {
        el.textContent = el.textContent.replace(new RegExp(index, 'g'), num);
    });
};

function traverseToLeaf (el) {
    if (el.childNodes.length === 0) return;

    el
        .childNodes
        .forEach(node => {
            if (node.nodeType === 3) {
                numbersToPersian(node);
                } else {
                traverseToLeaf(node);
            }
        });
};

// just write your element class or ID instead of '.primary' in line below
traverseToLeaf(document.querySelector('.primary'));
于 2018-12-29T01:57:27.077 回答
0
function persianNumber(string) {
    return string.split('0').join('۰')
    .split('1').join('۱')
    .split('2').join('۲')
    .split('3').join('۳')
    .split('4').join('۴')
    .split('5').join('۵')
    .split('6').join('۶')
    .split('7').join('۷')
    .split('8').join('۸')
    .split('9').join('۹')
}
于 2019-01-23T07:51:54.103 回答
0

ES6 单行

基于@mcrunix 答案的函数:

fa2enDigits 返回用英文数字替换波斯数字的字符串:

const fa2enDigits = s => s.replace(/[۰-۹]/g, w => String.fromCharCode(w.charCodeAt(0) - 1728) )

en2faDigits 返回用波斯数字替换英文数字的字符串:

const en2faDigits = s => s.replace(/[0-9]/g, w => String.fromCharCode(w.charCodeAt(0) + 1728) )

例子:

const fa2enDigits = s => s.replace(/[۰-۹]/g, w => String.fromCharCode(w.charCodeAt(0) - 1728) )

const en2faDigits = s => s.replace(/[0-9]/g, w => String.fromCharCode(w.charCodeAt(0) + 1728) )


console.log('Tel: ۰۹۱۲', '=>' , fa2enDigits('Tel: ۰۹۱۲') );
console.log('Tel: 0912', '=>' , en2faDigits('Tel: 0912') );

于 2021-09-10T06:41:38.370 回答