Как заменить цифры в теле на персидские числа?
Я хочу преобразовать все числа в 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
Вы можете использовать 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 "";
}