Как заменить цифры в теле на персидские числа?

Я хочу преобразовать все числа в 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>

persian = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹');
english = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');

Благодарю.

15 ответов

Решение

Вы можете использовать этот метод: ( 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]);
    }
}

Этот пример заменит числа на всей странице:

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];
}

Я написал этот короткий и простой код.

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

console.log(result);

Если вы хотите выбрать некоторые элементы 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>

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

Примеры:

<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

Вы можете использовать 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;
}

  • В коде предполагается, что все исходные числа в HTML представлены в английском формате (в котором используется запятая для разделителя тысяч и точка для десятичного разделителя).

  • Я использовал модифицированную версию ответа Sjoerd здесь. Спасибо ему за его ответ.

    Список различных распространенных числительных см. в этой статье в Википедии . Также см. этот пост и этот пост . Вы также можете использовать библиотеку persian.js, чтобы сделать все это.

    Вот этот findAndReplaceDOMText.js, который может вам помочь. Он проходит по всем узлам документа (в отличие от всех элементов) и заменяет текст, когда nodeType аргумент равен 3, который является TEXT_NODE.

    Если вы хотите использовать его для определенного элемента или селектора, это может помочь:

    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");
    

    Работал на меня!

    просто поместите его в тег span или p с определенным классом и измените шрифт этого класса на персидский шрифт, например «B yekan». я тестировал.работает.

    Еще один простой способ:

    String.prototype.toEnglishDigits = function () {
         var charCodeZero = '۰'.charCodeAt(0);
    
         return this.replace(/[0-9]/g, function (w) {
             return String.fromCharCode(parseInt(w) + charCodeZero);
          });
    }
    
    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('۹')
    }
    

    Чуть более понятный фрагмент:

    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'));
    

    Все способы не уверены, потому что многие персидские пользователи, использующие арабскую клавиатуру, и арабские символы отличаются от персидских чисел.

    лучше заменить арабские буквы тоже.

    например, это нулевой символ на персидском языке: ۰ и это нулевой символ на арабском языке: ٠

    как видите, оба одинаковы, но их Unicode не одинаковы. если вы используете персидский в своем проекте, я рекомендую вам persian.js, это всего лишь 5 КБ.

    или если вы не хотите использовать эту библиотеку, вы можете использовать этот код:

    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;
    }
    
      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 "";
      }
    
    Другие вопросы по тегам