1 (изменено: Евген, 2012-02-15 09:46:35)

Тема: JavaScript: форматирование числа

Коллеги, приветствую !
Недавно начал изучать JS (до этого изучал VBS), грызу зубами, зубы крошатся... но результат появляется потихоньку...
сейчас столкнулся со следующей задачей, имеется число (например 1 или 10 или 12) нужно получить строковое представление числа в формате  5-и знаков, например соответственно "00001","00010","00012", т.е. спереди доставить нулей...
Конечно можно перевести число в строковое представление, измерить длинну и в цикле добавить недостающих нулей, но подозреваю, что это можно сделать "красивее" так сказать "грамотнее"
В силу "не большого" опыта кодирования в JS ещё не знаю всей его функциональности...
Заранее фэнкс...

Вот например в VBA это делалось strResult=Format(exp,"#####") - просто и вкусно, здесь пока что теряюсь...

Времени не хватает... :-(

2

Re: JavaScript: форматирование числа

function format(aInt){return(('00000'+aInt).substring((''+aInt).length));}

3

Re: JavaScript: форматирование числа

('0000000000000'+10).match(/.{5}$/)

Я конечно далек от мысли... (с)

4 (изменено: stir, 2012-02-15 10:48:14)

Re: JavaScript: форматирование числа

Сталкивался с этим..но увы победить сразбегу не смог. С полнотой теоритических возможностей так и не познакомился, поэтому пришлось менять способ ввода-вывода информации (циклы, строки, массивы с применением арифметики и т.п.)...
При выводе даже полученного числа текстом '0'+'0'+'0'+'1'.. происходит автопреобразование в подходящий тип - число и соответственно математическое сложение чисел, т.е. в итоге я получал одну цифру - 1. Я заморачиваться не стал- изменил свой принцип создания и поиска согласно этой логики скрипта.
Может гуру форума что - нибудь подскажут..

Любители построили Ковчег, а профессионалы - Титаник.

5 (изменено: stir, 2012-02-15 11:07:51)

Re: JavaScript: форматирование числа

Пока писал пост.. ответы появились.. .

Serge Yolkin, более подробно прочел информацию о методе substring... лично сам не решился бы его применять  в таком ключе в своем коде сейчас (Если начало больше конца, то они меняются местами, объект.substring(начало [,конец])).

Любители построили Ковчег, а профессионалы - Титаник.

6 (изменено: Rumata, 2012-02-15 11:05:38)

Re: JavaScript: форматирование числа

var n = 4;
var s = ('00000' + n).slice(-5);

Если надо дополнять произвольным количеством нулей, то


function format(value, c, n)
{
	var padding = new Array(n + 1).join(c);
	return (padding + value).slice(-n);
};

Только не стоит пользоваться этой функцией в цикле, лучше сделать как в примере выше.

( 2 * b ) || ! ( 2 * b )

7

Re: JavaScript: форматирование числа

('000000000000000'+10).replace(/^.+(.{5})$/,'$1')

но slice красивее, забыл о его существовании

Я конечно далек от мысли... (с)

8

Re: JavaScript: форматирование числа

Да, Rumata, как всегда на высоте, восхищаюсь вполне понятными и простыми решениями!

Любители построили Ковчег, а профессионалы - Титаник.

9

Re: JavaScript: форматирование числа

всем, выше запостившим спасибо большое за подкинутую идею, я наконец-то сделал у себя на VBS подобную вещь

num = 12
MsgBox(Right("00000"&num, 5))
Кодинг, как много в этом слове...

10

Re: JavaScript: форматирование числа

Блин, коллеги, СПАСИБО !!!
Столько вариантов !!!

Времени не хватает... :-(

11

Re: JavaScript: форматирование числа

Евген пишет:

[..]
имеется число (например 1 или 10 или 12) нужно получить строковое представление числа в формате  5-и знаков, например соответственно "00001","00010","00012", т.е. спереди доставить нулей...
[..]

Помнится что, я на заре своего скриптописания на vbscript подобную задачу решал так - добавлял к интересующему числу, например, сто тысяч (100000), перед выводом преобразовывал в строку и брал только правые 5 символов, т.е. без ведущей "1".

WBR. Roman

12

Re: JavaScript: форматирование числа

Какая получается ветка интересная. Позвольте еще такую задачу предложить.

Имеется строка состоящая только лишь из цифр, где длина строки кратна 6.

(000001000120000038000038000009000014000015000015000004...)

Требуется разбить строку на n частей по 6 символов.

Ничего сложного но, ОЧЕНЬ хочется посмотреть на разнообразие вариантов.

Нас невозможно сбить с пути, нам пофигу куда идти.

13 (изменено: smaharbA, 2012-02-16 09:27:40)

Re: JavaScript: форматирование числа

.match(/.{6}/g)

правильнее так наверное

.match(/.{6}|.{1,}$/g)

Я конечно далек от мысли... (с)

14 (изменено: Rumata, 2012-02-16 12:19:58)

Re: JavaScript: форматирование числа

smaharbA, так короче


.match(/.{6}|.+/g)

.
Этот метод хорош тем, что возвращает все подстроки, включая короткие. Например:


'1234567'.match(/.{6}|.+/g); // ['123456', '7']

.
Если рассматривать этот способ как "разделение слева", то у него должен быть и соответствующий антипод - "разделение справа". Однако здесь решение не так очевидно и требует некоторой сноровки. Я вспомнил, как однажды встречал решение для разбиения целых чисел на тысячи. Вот его модификация под текущую задачу:


'1234567'.split(/(?=(?:.{6})+$)/); // ['1', '234567']

.
С последним примером вышло недоразумение, связанное с ошибкой алгоритма обработки регулярного выражения в JScript 5.7 на Vista Enterprise SP2. В связи с этим регулярно выражение исправлено - было /(?=(.{6})+$)/. А вообще-то надо поразмышлять кто правее (МСИЕ или все остальные)

Хотя в задаче стоял вопрос разбиении строки, состоящей только из цифр (\d), но с легкой руки коллеги smaharbA, я расширил решение для любых символов (.).

( 2 * b ) || ! ( 2 * b )

15 (изменено: DnsIs, 2012-02-16 11:40:45)

Re: JavaScript: форматирование числа

Спасибо Гуры .

Rumata пишет:
'1234567'.split(/(?=(.{6})+$)/); // ['1', '234567']

Честно говоря, пока еще недоперепонял как вообще такое работает. 8)
И возвращает сие шаманство ['1', '234567', '234567']

Нас невозможно сбить с пути, нам пофигу куда идти.

16

Re: JavaScript: форматирование числа

DnsIs пишет:

пока еще недоперепонял как вообще такое работает

Сам долго "входил" в него. Потом расскажу.

DnsIs пишет:

И возвращает сие шаманство ['1', '234567', '234567']

Вы уверены? Версию ОС, WSH, браузера, JScript!

( 2 * b ) || ! ( 2 * b )

17

Re: JavaScript: форматирование числа

Firefox 11.0 -> Простой редактор JavaScript (Shift + F4)

s = '1234567'.split(/(?=(.{6})+$)/);
alert(s);

Alert:

1,234567,234567
Нас невозможно сбить с пути, нам пофигу куда идти.

18 (изменено: Rumata, 2012-02-16 11:59:45)

Re: JavaScript: форматирование числа

DnsIs
Прошу прощения... Писал пример в консоли с запущенным JScript 5.7, Vista Enterprise SP2. Все остальные браузеры и интерпретаторы показывают результат аналогично Вашему. Но мне хотелось бы знать Ваше окружение.

Вот так правильно


'1234567'.split(/(?=(?:.{6})+$)/)

upd:
В общем-то все ответы получены.
Заодно поправлю свое сообщение где первоначально упоминается неверный вариант.

( 2 * b ) || ! ( 2 * b )

19

Re: JavaScript: форматирование числа

Rumata пишет:

Но мне хотелось бы знать Ваше окружение.

Что именно хотел знать, какая винда? XP Home XP3; WSH 5.7

Кстати Jscript действительно возвращает ['1', '234567'].

Нас невозможно сбить с пути, нам пофигу куда идти.

20

Re: JavaScript: форматирование числа

alert((xxx.split(...)).constructor);
alert((xxx.match(...)).constructor);

Я конечно далек от мысли... (с)

21

Re: JavaScript: форматирование числа

smaharbA пишет:

alert((xxx.split(...)).constructor);
alert((xxx.match(...)).constructor);

Похоже я тупой. Я вас не понял. Разъясните пожалуйста.

Нас невозможно сбить с пути, нам пофигу куда идти.

22 (изменено: smaharbA, 2012-02-17 08:35:07)

Re: JavaScript: форматирование числа

посмотрите, что выведет

alert(('000001000120000038000038000009000014000015000015000004'.split(/(?=(?:.{6})+$)/)).constructor);

и поймете

Я конечно далек от мысли... (с)

23

Re: JavaScript: форматирование числа

Получаю вот что (firefox 11.0):

function Array() {
  [native code]
}

Все равно не догоняю.

Нас невозможно сбить с пути, нам пофигу куда идти.

24

Re: JavaScript: форматирование числа

DnsIs, все верно. Коллега smaharbA показал, что результатом выполнения методов .split и .match являются массивы. Массив в JS это объект, чей конструктор - встроенная функция Array.

У меня вопрос к smaharbA. С какой целью Вы показали это?

( 2 * b ) || ! ( 2 * b )

25

Re: JavaScript: форматирование числа

Rumata пишет:

У меня вопрос к smaharbA. С какой целью Вы показали это?

Собственно я это тоже хотел спросить.  Просто не так выразился.

Нас невозможно сбить с пути, нам пофигу куда идти.

26 (изменено: Serge Yolkin, 2012-03-26 23:18:34)

Re: JavaScript: форматирование числа

В данной ветке это оффтоп, но боюсь далеко отходить от такого колдунства:

Rumata пишет:

/(?=(?:.{6})+$)/

Поскольку обещанного рассказа пока не последовало, может, кто поможет разобрать параметры oHTA.commandLine:
  "C:\Utils\check.hta" file1.txt "file1 - Копия.txt" name3new.txt file.log "filename archive.zip"
проблема в том, что имена с пробелами - в кавычках, а без пробелов - без кавычек. Сейчас разбираю в цикле (while): если первый символ (") отрезаем до следующей кавычки, иначе - до следующего пробела. В общем, работает, но, может, есть такой же изящный способ? Мои эксперименты пока результатов не дали...

В идеале надо получить массив:
  pArr[0]=C:\Utils\check.hta
  pArr[1]=file1.txt
  pArr[2]=file1 - Копия.txt
  ...

Если параметры не переданы, pArr.length=1 (только путь к .hta)

27

Re: JavaScript: форматирование числа

Serge Yolkin, проверьте

var S='"C:\\Utils\\check.hta" file1.txt "file1 - Копия.txt" name3new.txt file.log "filename archive.zip"';

function GetArguments(ParamStr)
{
    var flag = /^ *"/.test(ParamStr)?1:0;
    var parts = ParamStr.replace(/^ *"|" *$/g,"").split('"'),
    result=[];
    
    for (var i=0,l=parts.length,item=""; i<l; i++)
    {
        item = parts[i].replace(/^ *| *$/g,"");
        if (i%2!=flag) result.push('"'+item+'"'); else result.push('"'+item.replace(/ +/g,'""')+'"');
    }
    return result.join("").replace(/^ *"|" *$/g,"").split(/""/g); 
}

WScript.Echo(GetArguments(S));

28

Re: JavaScript: форматирование числа

JSman
Работает. И подход оригинальный - не сразу разобрался. Но хочется... красоты, что ли.
Вот, за два часа экспериментов сваял:

var S='"C:\\Utils\\check.hta" file1.txt "file1 - Копия.txt" name3new.txt file.log "filename archive.zip"';

function GetArguments(ParamStr){
    return ParamStr.match(/(\"[^\"]+\")|(\S+)/g);
}

WScript.Echo(GetArguments(S));

Только кавычки мешаются. И спать пора. Завтра еще поэкспериментирую. RegExp'ы - великая сила. Или её тёмная сторона.

29 (изменено: Rumata, 2012-03-27 04:20:41)

Re: JavaScript: форматирование числа

Serge Yolkin пишет:

Поскольку обещанного рассказа пока не последовало

Хм. Виноват. Забыл-с. Да и тема несколько "поутихла". Коли Вы ее подняли, значит время поделиться рассказом.

Впервые об этой конструкции я узнал в контексте форматирования же чисел с разделением тысячей, например, 123456789 отформатировать в 123 456 789 (в русской традиции еще принято использовать точки, в то время как на западе принято выделять тысячи запятыми - 123,456,789). Все бы было легко и просто, но проблема заключается в поиске троек справа, то есть с конца строки. Для понимания этого регулярного выражения давайте его перепишем в стиле языка Perl, "столбиком", и прокомментируем каждую значимую строку:

/
	(?=			# "заглянуть вперед" и найти соответствие
		(?:		# без запоминания подстроки, 
			.{6}   # состоящей из 6 символов. 
		)+		 # возможно несколько таких подстрок
		$		  # до конца всей строки
	)
/

Вся хитрость в том, что (?=шаблон), "заглядывая вперед" ищет на соответствие шаблону, но найденное соответствие не запоминает, и поиск продолжается с позиции, следующей за найденным соответствием, без учета "заглядывания вперед". Вот пример.


'to be or not to be. To be or not to be.'.match(/to be(?=\s)/ig)

Данное регулярное выражение соответствует всем (модификатор g) вхождениям подстроки "to be ", "To be " без учета регистра (модификатор i), но не соответствует ни одному вхождению подстрок "to be.".

В нашем же случае мы ищем подстроки, состоящие из 6 любых символов ".{6}". И таких подстрок, идущих подряд  до конца строки "$", мы допускаем неограниченное количество - квантификатор "+". Так как у нас указано, что найдя необходимое соответствие "(?=)" и не запоминая его, идти далее, то поиск продолжается со следующей, непосредственно ближайшей позиции в строке.

Таким образом, это регулярное выражение находит все позиции между символами в строке, где все символы сгруппированы по 6 символов, начиная с конца.

Еще одна иллюстрация:

var s = '0123456';
var re = /(?=(\d\d\d)+$)/g;

var t = s.replace(re, ' ');

alert(s);
alert(t);

Это регулярное выражение применяется к нулевой позиции в строке (перед символом "0") - 012, 345, 6. Не подходит, потому что группы по 3 цифры должны идти до конца строки.
Переходим к следующей позиции (перед символом "1") - 0, 123, 456. Соответствует. В этом месте вставляем замену - строку из одного пробела.
Переходим к следующей позиции - 01, 234, 56. Дальше - 012, 345, 6.
Доходим до 0123, 456. Подходит - вставляем еще один символ пробела и завершаем поиск, так как срока исчерпала себя.

( 2 * b ) || ! ( 2 * b )

30 (изменено: Rumata, 2012-03-27 02:19:52)

Re: JavaScript: форматирование числа

Serge Yolkin пишет:

/(\"[^\"]+\")|(\S+)/g

Экранировать кавычки не обязательно.

Serge Yolkin пишет:

разобрать параметры oHTA.commandLine

как вариант:

var re = /"(.*?)"(?:\s+|$)|([\S]+)/g;
var r;
while ( r = re.exec(s) ) {
    var arg = r[1] || r[2];
    alert(arg);
}
( 2 * b ) || ! ( 2 * b )

31

Re: JavaScript: форматирование числа

Rumata
Большое спасибо за разъяснение! Если бы вся инфа по регэкспам такая же внятная была - на них можно было бы в любви объяснятся
И за вариант спасибо. Но и со своими идеями ещё поиграюсь.

А кавычки я экранирую потому, что иначе Akel с моим оригинальным файлом подсветки регэкспы неправильно подсвечивает. Пока не поборол.

32

Re: JavaScript: форматирование числа

Serge Yolkin
Не за что. На счет любви - не знаю, но некоторые задачи с их помощью решаются очень лаконично и красиво. Главное не увлекаться и не злоупотреблять ими.

( 2 * b ) || ! ( 2 * b )

33

Re: JavaScript: форматирование числа

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

Нас невозможно сбить с пути, нам пофигу куда идти.

34

Re: JavaScript: форматирование числа

Rumata, а твой пример гораздо круче, чем мой получился . Я даже забыл, что такой простой код можно писать.

35 (изменено: Serge Yolkin, 2012-03-30 14:24:39)

Re: JavaScript: форматирование числа

Поигрался. Уважаемый Rumata предложил абалденный алгоритм. Преобразование комстроки в массив параметров, практически, занимает одну строчку:

while(r=re.exec(HTApp.commandLine)){pArr.push(r[1]||r[2]);}

Причем, не важно - файлы там, или нет. Если скрипт (сценарий) требует дополнительный ключ ( [script].hta /a file.ext ... ) - ничего менять не надо, ключ будет в pArr[1]. И получение данных из такого массива не сложнее:

while(pArr.length>1){ // если есть доп. ключ - >2
    processingFunction(pArr.pop());
}

Не знаю, как посчитают уважаемые форумчане, а в свою коллекцию я это уже добавил. Управление hta из комстроки стало не сложнее, чем в wsf. Еще раз спасибо Rumata.

36 (изменено: wisgest, 2014-03-04 22:22:30)

Re: JavaScript: форматирование числа

Продолжу оффтопик на тему разбора командной строки HTA.

Serge Yolkin пишет:

Уважаемый Rumata предложил абалденный алгоритм. Преобразование комстроки в массив параметров, практически, занимает одну строчку

Вы же сами в сообщении #28, используя метод .match(), уложились в единственный оператор! Я, правда считаю, что правильнее использовать другое регулярное выражение:

var Args=CommandLine.match(/(?:"[^"]*(?:"|\S)|\S)+/g);

— строка разделяется по подряд стоящим пробельным символам, не заключаемым между нечётной и чётной кавычками, считая их от начала строки, т.е. если ближайшая слева (для пишущих слева направо ) кавычка чётная, то пробельный символ не включается ни в какой из параметров, в противном случае — включается; в случае нарушения чётности числа кавычек — пробельные символы в конце строки теряются.

Такое же разделение за исключением того, что при нарушение чётности числа кавычек пробельные символы в конце строки будут не теряться, а включаться в последний параметр:

/(?:"[^"]*(?:"|)|\S)+/g

Замечу, что если в рассматриваемой строке не будет найдено ни одного совпадения,
т.е если командная строка пустая, что возможно в зависимости от способа запуска HTA (например, при запуске по ссылке из IE (после подтверждения)),
или она состоит их одних лишь пробельных символов (чего в данном случае быть не должно)
.match() вернёт значение null; если же в любом случае нужен массив, хотя бы и пустой:

var Args=CommandLine.match(regex)||[];

--------
В случае, если аргументы командной строки пердставляют собой список разделённых пробельными символами имён файлов, некоторые из которых, возможно, заключены в кавычки и при этом, возможно, содержат пробелы, разбор командной строки по правилам предложенным мною и другими уважаемыми соучастниками (Serge Yolkin, Rumata), по всей вероятности, не будет различаться, но в общем случае может не совпадать (проверено).

Берусь утверждать, что моё правило более правильное , т.к:
• по тому же правилу (с выбрасываньем лишних пробельных символов в конце при нарушении чётности числа кавычек) разбирается командная строка в командных файлах CMD.EXE за исключением того, что запятые и точки с запятой в командной строке приравнены к пробельным символам;
• по тому же правилу (без выбрасывания лишних пробельных символов в конце при нарушении чётности числа кавычек) разбирается командная строка в сценариях WSH и консольных приложениях на MS Visual С/C++ 6.0 за исключением того, что после разбора из параметров удаляются все кавычки (не только внешние!!);
• тем же правилом руководствуется сам MSHTA.EXE выделяя из списка своих параметров первый — путь к приложению (и оставляя остальные на усмотрение этого приложения); при этом если путь открывается кавычкой, то кавычкой он должен и закрываться — эти внешние кавычки в путь не включаются, но внутри них могут быть и другие кавычки; также символы, в частности кавычки и пробелы, в пути можно заменять их escape-кодами — это можно использовать во избежание распадения пути на части и для соблюдения баланса кавычек — такие сложные пути могут быть при использовании, например, протокола «javascript:», чтобы в этом убедиться рассмотрите команды:

mshta.exe javascript:"Hello,   world!"; А это уже дополнительные параметры
mshta.exe "javascript:  alert ( "Hello,%20world!%22);%20"Текст, который будет выведен на странице";"
mshta.exe "javascript:  alert ( "Hello,%20world!%22);%20"Текст, который будет выведен на странице%22;" А это уже дополнительные параметры
mshta.exe javascript:alert('" - это кавычка'); location.href; // А это всё ещё путь к приложению, а не его аргументы

37 (изменено: Serge Yolkin, 2012-04-16 19:23:04)

Re: JavaScript: форматирование числа

wisgest

Serge Yolkin in #28 пишет:

Только кавычки мешаются.

Т.е. при использовании match потребуется доп. операция - убрать из параметра (элемента массива) обрамляющие кавычки (если они там есть). Для всяких там fileExist, или getFile они будут мешать. А способ, предложенный Rumata убирает их автоматом, чем мне и понравился.

38

Re: JavaScript: форматирование числа

На всякий случай предлагаю посмотреть в тему HTA/JScript: Автоматический разбор параметров командной строки.

( 2 * b ) || ! ( 2 * b )