jscript: преобразовать числа к одному формату
От: Рома Мик Россия http://romamik.com
Дата: 06.12.05 20:01
Оценка:
Итак есть тестовая переменная, в которой выражение предназначенное для того, чтобы перредать его функции eval. Одна беда, чилса в нем могут быть в виде
123,168.99
123'168.99
123 168,99
123168.99
123168,99
и т.д.
Надо написать код на jscript, который найдет все числа, правильно их распознает и приведет к виду 123168.99. На самом деле задача не однозначная, например 123,168 можно понять двумя способами, но в этом случае должно получиться 123.168. Вопрос как правильно такой код написать? Вроде начал писать регекспы, но больно уж запутано получается...
... << RSDN@Home 1.2.0 alpha rev. 619>>
Re: jscript: преобразовать числа к одному формату
От: Bereal Россия bereal.ru
Дата: 07.12.05 08:50
Оценка:
Здравствуйте, Рома Мик, Вы писали:

РМ>Итак есть тестовая переменная, в которой выражение предназначенное для того, чтобы перредать его функции eval. Одна беда, чилса в нем могут быть в виде

РМ>123,168.99
РМ>123'168.99
РМ>123 168,99
РМ>123168.99
РМ>123168,99
РМ>и т.д.
РМ>Надо написать код на jscript, который найдет все числа, правильно их распознает и приведет к виду 123168.99. На самом деле задача не однозначная, например 123,168 можно понять двумя способами, но в этом случае должно получиться 123.168. Вопрос как правильно такой код написать? Вроде начал писать регекспы, но больно уж запутано получается...

Если предположить что у чисел всегда будет дробная часть то примерно так (очень на вскидку):
на php (на js перепишешь сам надеюсь):

$str = preg_replace('#(.*)(\.|,)#', "$1k", $str);
$str = preg_replace('#[^\dk]#', '', $str);
The God is Real ... unless declared as Integer
Re: jscript: преобразовать числа к одному формату
От: virka  
Дата: 07.12.05 10:00
Оценка:
Здравствуйте, Рома Мик, не совсем понятны исходные данные. Какой тип тестовой переменной? Строка? Что она содержит? Строку, в тексте которой встречаются эти числа, или только псевдочисла по-отдельности? Что такое и т.п.? Какик еще могут быть варианты?
Re[2]: jscript: преобразовать числа к одному формату
От: Рома Мик Россия http://romamik.com
Дата: 07.12.05 11:31
Оценка:
Здравствуйте, virka, Вы писали:

V>Какой тип тестовой переменной? Строка?

Да, строка.

V>Что она содержит? Строку, в тексте которой встречаются эти числа,

Да. Причем это математическое выражение, т.е. кроме чисел там скорее всего встречаются только скобки и знаки арифметических операций, хотя я бы не стал на это полагаться.

V>Какик еще могут быть варианты?

([0-9]{1,3})?([,'` ][0-9]{3})*([\.,][0-9]*)?
Это очевидно неверное рег. выражение: как минимум (а) все символы разделители тысяч в одном числе одинаковые, (б) если уж запятая разделяет тысячи, то точка отделет дробную часть. Но смысл я думаю ясен.
... << RSDN@Home 1.2.0 alpha rev. 619>>
Re[3]: jscript: преобразовать числа к одному формату
От: virka  
Дата: 08.12.05 13:20
Оценка: 7 (1)
Здравствуйте, Рома Мик, могу предложить такой вариант, не знаю, насколько он подойдет.
С рег.выражениями не сталкивался, так получилось, поэтому предлагаемый вариант без них.
Наверняка, есть гораздо более элегантное и мощное решение, Вам прийдется его поискать.
Предлагаемое решение исходит из таких допусков:
1. Знак пробела между числами означает разделитель одного числа, а не разделяет разные числа. В последнем случае нужно использовать хотя бы два символа пробела подряд.
2. Лишние пробелы в выражении убираются.
3. Число может иметь только два различных типа разделителя (например, 123,456,567.34 или 123'456'567,34 , а не 123,456'567.34)
4. При наличии двух различных типов разделителей последний преобразуется в точку, остальные отбрасываются.
5. При наличии в числе только одного разделителя он преобразуется в точку, если это запятая, в остальных случаях отбрасывается.
6. Выражения типа 67467jsdhfh8329 могут обрабатываться некорректно (в большинстве случаев остаются как есть).

Ниже приводится функция, посмотреть ее работу можно по адресу http://www.1961.ru/science/js/lrnTestValues.htm

//функция обработки чисел в строковом выражении
function convertNumberDot()
{
var src=arguments[0];//передаваемое выражение
var en=6;//максимальная степень чисел (т.е кол-во разделителей в числе 123 234 345 456 789.345 (в данном случае 5)

//вспомогательные переменные
var rez="";
var rezbr=new Array();
var tmp1, tmp2, tmp3, tmp4, tmp5;
var hlp1, hlp2, hlp3, hlp4;
var tmpcoa;
//

src=src.split("\r\n");//разбиваем выражение на строки
for(aco=0;aco<src.length;aco++)
{
tmp1=src[aco].split(" ");//разбиваем строку по пробелам
var rezar=new Array();
var passco=0;
for(bco=0;bco<tmp1.length;bco++)
{
tmp2=tmp1[bco];
if(tmp2!="")
{
tmp3=parseInt(tmp2);
hlp1=String(tmp3).length;
if(!isNaN(tmp3))//проверка на число
{
tmpcoa=bco;
for(cco=1;cco<en;cco++)//собираем число с разделителем в один пробел (глубина сборки определяется величиной en)
{
if(!isNaN(parseInt(tmp1[tmpcoa+cco])))//проверка на число следующего элемента
{
tmp2=tmp2+" "+tmp1[tmpcoa+cco];
bco++;
}
else{break;}
}//for(cco=1;cco<enum;cco++)

if(hlp1<tmp2.length)//если в числе присутствуют нечисловые элементы (предполагается, что разделители)
{
hlp2=tmp2.substring(hlp1,hlp1+1);//вырезание нечислового символа (предполагается, что разделителя)
tmp3=tmp2.split(hlp2);//разбивка по этому символу числа
tmp4=tmp3[tmp3.length-1];//последний элемент полученного массива
hlp1=String(tmp4).length;
hlp3=String(parseInt(tmp4)).length;
if((!isNaN(parseInt(tmp4)))&&(tmp4.substring(0,1)!=" "))//последний элемент число и не начинается с пробела (проверка)
{
if(hlp3<hlp1)//если этот последний элемент содержит другой нечисловой элемент (предполагается, что один), то он заменяется на символ "точка" (.)
{
hlp4=tmp4.substring(hlp3,hlp3+1);
tmp5=tmp4.split(hlp4);
(tmp5[1]=="")?(tmp4=tmp5.join("")):(tmp4=tmp5.join("."));//если второй разделитель — это последний символ, то он отбрасывается
tmp3[tmp3.length-1]=tmp4;
tmp2=tmp3.join("");
}//if(hlp3<hlp1)
else if((tmp3.length==2)&&(hlp2==","))//если нет, но разделитель один и это символ "запятая" (,), то он заменяется на символ "точка" (.)
{
tmp2=tmp3.join(".");
}//else if((tmp3.length==2)&&(hlp2==","))
else// в противном случае все разделители отбрасываются
{
tmp2=tmp3.join("");
}//else
}//if(!isNaN(tmp4))
}//if(hlp1<tmp2.length)
}//if(!isNaN(parseInt(tmp2)))
rezar[passco]=tmp2;
passco++;
}
}//for(bco=0;bco<tmp1.length;bco++)
rezbr[aco]=rezar.join(" ");// сборка строки
}//for(aco=0;aco<src.length;aco++)
rez=rezbr.join("\r\n");// сборка выражения по строкам
return rez;
}
Re[4]: jscript: преобразовать числа к одному формату
От: Рома Мик Россия http://romamik.com
Дата: 08.12.05 14:31
Оценка:
Здравствуйте, virka, Вы писали:

Спасибо за потраченные усилия. Но результат, что называется неверный, например:
222 444 +333,344.444 --> 222444+,44.444
Впрочем, если нет собственного интереса, то править ошибки не стоит, т.к. мне было интересно именно как правильно, т.е. с минимальными усилиями получить результат, в данном случае это очевидно регулярные выражения.
Re[4]: jscript: преобразовать числа к одному формату
От: Mamut Швеция http://dmitriid.com
Дата: 08.12.05 15:43
Оценка: +1
V>5. При наличии в числе только одного разделителя он преобразуется в точку, если это запятая, в остальных случаях отбрасывается.

Не сработает на американском разделении тысяч: 33,445,566 — это 33 миллиона 445 тысяч 566.
... << RSDN@Home 1.2.0 alpha rev. 619>>


dmitriid.comGitHubLinkedIn
Re[5]: jscript: преобразовать числа к одному формату
От: virka  
Дата: 09.12.05 11:49
Оценка:
За потраченные усилия благодарить не стоит, не было бы собств.желания и времени — не было б и усилий.
Делаю работу и немного "загрюз", захотелось развеяться.
По поводу предыдущего скрипта предполагалось, что выражения типа 123+234 будут писаться 123 + 234, в общем, все тонко и звонко.
Раз появилась такая возможность, немного поизучал рег.выражения, вот еще вариант.
Называется, "почуствуйте разницу", по объему и сложности скрипт конечно сильно сократился.
Не знаю, подойдет, такие условности:
1. Предполагается, что знак дроби — только точка "." или запятая ","
2. Все остальные разделители в числе сбрасываются.
3. Знак запятой, если один в числе — преобразуется в точку, если их больше одной — сбрасываются
4. Скрипт не имеет понятия о разделителях тысяч — т.е. он не ведет счет "на три", а обрабатывает все нечисловые элементы, окруженные числами.
5. Два числа, разделенные одним пробелом считаются одним числом, пробел отбрасывается.
6. Лишние пробелы не скидываются.

Функция —

//функция обработки чисел в строковом выражении
function convertNumberDot()
{
var src=arguments[0];//передаваемое выражение

//вспомогательные переменные
var rezar=new Array();
var rezbr=new Array();
//
var regexpnumb=/(\d+([,.'" ]\b)?)+|\D+/gi; //рег.выраж поиска чисел
var regexpdot=/\D+|\d+/gi; //рег.выраж поиска бяк в числах

rezar=src.match(regexpnumb); //разбиваем на массив "мухи отдельно, котлеты отдельно"
for(aco=0;aco<rezar.length;aco++)
{
if(!isNaN(parseInt(rezar[aco]))) //если муха
{
rezbr=rezar[aco].match(regexpdot);
if(rezbr!=null)
{
var boolfirst=true;
for(bco=rezbr.length-1;bco>=0;bco--)
{
if((isNaN(parseInt(rezbr[bco])))&&(rezbr[bco]!=rezar[aco].substring((rezar[aco].length-1),rezar[aco].length))) //первый с конца разделитель
{
if((boolfirst)&&((rezbr[bco]==",")||(rezbr[bco]=="."))) //если запятая или точка — ставим точку
{
rezbr[bco]=".";
boolfirst=false;
}//if((boolfirst)&&(rezbr[bco]==","))
else
{
rezbr[bco]=""; //в противном случае сбрасываем
}
}//if(rezbr[bco]!=rezar[aco].substring((rezar[aco].length-1),rezar[aco].length))
}//for(bco=rezbr.length-1;bco>=0;bco--)
}//if(rezbr!=null)
rezar[aco]=rezbr.join(""); //сборка
}//if(!isNaN(parseInt(rezar[aco])))
}//for(aco=0;aco<rez.length;aco+)
return rezar.join(""); //сборка и возврат
}

Посмотреть ее работу можно там же http://www.1961.ru/science/js/lrnTestValues.htm
Re[6]: jscript: преобразовать числа к одному формату
От: Рома Мик Россия http://romamik.com
Дата: 09.12.05 14:40
Оценка:
Здравствуйте, virka, Вы писали:

123,456,789 --> 123456.789, а должно быть 123456789
... << RSDN@Home 1.2.0 alpha rev. 619>>
Re[7]: jscript: преобразовать числа к одному формату
От: virka  
Дата: 09.12.05 19:26
Оценка:
Правда Ваша, Рома Мик. Опять я ошибся. Исправил.
Re[8]: jscript: преобразовать числа к одному формату
От: Рома Мик Россия http://romamik.com
Дата: 09.12.05 19:40
Оценка:
Здравствуйте, virka, Вы писали:

V>Исправил.

Вот еще:
123,123,123 123 -> 123123123123
но
123,123,123  123 -> 123123123  123

... << RSDN@Home 1.2.0 alpha rev. 619>>
Re[9]: jscript: преобразовать числа к одному формату
От: virka  
Дата: 09.12.05 21:03
Оценка: 7 (1)
Исправил, но не на все случаи. Скрипт все усложняется.
Вариант 123,234 235,345 будет преобразован в 123.234 235.345 (скрипт посчитает разными числа 123.234 / 235.345)
но не вариант 123 345 456,458 345 (скрипт посчитает разными числа 123 / 345 / 456,458 / 345)
Все-таки на все случаи рецепта нет, какие-то правила нужно соблюдать.
Вообще-то я стараюсь не писать готовых скриптов (если не по работе), больше как в помощь (если получится) кому-нибудь изучать самому.
Последний вариант функции (если она Вам понадобится) можно найти на тестовой странице (просмотр HTML-кода).
Re: jscript: преобразовать числа к одному формату
От: anonymous Россия http://denis.ibaev.name/
Дата: 10.12.05 12:16
Оценка: 7 (1)
Здравствуйте, Рома Мик, Вы писали:

РМ>Итак есть тестовая переменная, в которой выражение предназначенное для того, чтобы перредать его функции eval. Одна беда, чилса в нем могут быть в виде

РМ>123,168.99
РМ>123'168.99
РМ>123 168,99
РМ>123168.99
РМ>123168,99
РМ>и т.д.
РМ>Надо написать код на jscript, который найдет все числа, правильно их распознает и приведет к виду 123168.99. На самом деле задача не однозначная, например 123,168 можно понять двумя способами, но в этом случае должно получиться 123.168. Вопрос как правильно такой код написать? Вроде начал писать регекспы, но больно уж запутано получается...

function convertNumbers(str) {
    function stringToNumber(str, stub1, tsd, stub2, dec) {
        return str.replace(new RegExp('\\' + tsd, 'g'), '').replace(new RegExp('\\' + dec), '.');
    }
    return str.replace(/\d{1,3}(([.,' ])?\d{3})*(([.,])\d+)?/g, stringToNumber);
}

var str = '123,168.99 + 123\'168.99 / 123 168,99 (123168.99 + 123168,99) - (33,445,566) * 123 / 345 + 678';
WScript.echo(str);
WScript.echo(convertNumbers(str));
Re[2]: jscript: преобразовать числа к одному формату
От: Рома Мик Россия http://romamik.com
Дата: 12.12.05 09:45
Оценка:
Здравствуйте, anonymous, Вы писали:


A>
A>function convertNumbers(str) {
A>    function stringToNumber(str, stub1, tsd, stub2, dec) {
A>        return str.replace(new RegExp('\\' + tsd, 'g'), '').replace(new RegExp('\\' + dec), '.');
A>    }
A>    return str.replace(/\d{1,3}(([.,' ])?\d{3})*(([.,])\d+)?/g, stringToNumber);
A>}
A>

С кодом пока не разбирался, но результат — иногда подглюкивает. Например:
12,222.233 -> 12,222233
Re[3]: jscript: преобразовать числа к одному формату
От: anonymous Россия http://denis.ibaev.name/
Дата: 12.12.05 10:03
Оценка: 36 (2)
Здравствуйте, Рома Мик, Вы писали:

РМ>С кодом пока не разбирался, но результат — иногда подглюкивает. Например:

РМ>12,222.233 -> 12,222233

тогда так
function convertNumbers(str) {
    function stringToNumber(str, stub1, tsd, stub2, stub3, dec) {
        return str.replace(new RegExp('\\' + tsd, 'g'), '').replace(new RegExp('\\' + dec), '.');
    }
    return str.replace(/\d{1,3}(([.,' ])?\d{3})?(\2\d{3})*(([.,])\d+)?/g, stringToNumber);
}
Re[4]: jscript: преобразовать числа к одному формату
От: Рома Мик Россия http://romamik.com
Дата: 12.12.05 19:10
Оценка:
Здравствуйте, anonymous, Вы писали:

А ведь работает! Осталось разобраться как...
... << RSDN@Home 1.2.0 alpha rev. 622>>
Re[5]: jscript: преобразовать числа к одному формату
От: anonymous Россия http://denis.ibaev.name/
Дата: 13.12.05 10:59
Оценка:
Здравствуйте, Рома Мик, Вы писали:

РМ>А ведь работает! Осталось разобраться как...


так спрашивай, что не понятно...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.