String.Format

    Те, кто пишут на C# очень хорошо знают и часто используют механизм String.Format, которого сильно не хватает в JavaScript. Несмотря на его простоту и удобство, на просторах Сети мало что можно накопать, в основном вариации на тему sprintf (привет сишникам). Достаточно давно был написан скрипт, который позволял форматировать строки на JavaScript и был похож на String.Format C#. Форматирование стало использоваться коллегами достаточно плотно в скриптах и я решил немного причесать код и опубликовать для тех, кто хочет получить String.Format в JavaScript.

    Итак, основные возможности:


    • Маркеры как в C#: {0}
    • Можно задавать используемую функцию форматирования: {0:d}
    • Можно передавать параметры функции форматирования: {0:n(,2)}
    • Можно регистрировать свои функции форматирования
    • Небольшой размер — 3.5Кб в упакованном виде
    • Работает быстро
    • Работает в IE, Chrome, Firefox (проверено), теоретически ничего не мешает работать в серверном JavaScript
    • Уже реализованы и встроены функции форматирования:
      • Форматирование массивов
      • Форматирование чисел
      • Форматирование даты и времени


    Использование


    Использовать можно 2-мя способами:
    1. Как в C#:
    var s = String.Format(format, arg0[, arg1[, arg2[...]]]);

    2. Как функция у любой строки:
    var s = 'format string {0}'.format(arg0[, arg1[, arg2[...]]]);

    Правила для маркеров

    {0} — значение будет преобразовано в строку по правилам JavaScript
    {0:f} — значение будет преобразовано в строку с помощью функции, зарегистрированной под именем f
    {0:f(p1,p2)} — значение будет преобразовано в строку с помощью функции, зарегистрированной под именем f и этой функции будут переданы параметры p1 и p2 в массиве, количество и правила для параметров зависят от самой функции, однако есть несколько общих правил:
    1. Параметры разделяются запятыми
    2. Все знаки в круглых скобках значимы т.е. для {0:f(p1,p2)} будет передано ['p1', 'p2'], а в случае {0:f(p1, p2)} будет передано ['p1', ' p2']
    3. Для маскирования запятой и закрывающей круглой скобки нужно использовать слэш: {0:f(p1\, p2)} будет передано ['p1, p2']
    4. Параметры можно пропускать: для {0:f(,p2)} будет передано ['', 'p2']
    5. Можно использовать вложенные маркеры: для {0:f({1})} будет передано ['значение_из_параметра_с_индексом_1'], в этом случае форматирование недопустимо, а значение передается то же, что было передано функции format

    Функции форматирования

    Все функции форматирования получают 2 параметры: значение, которое нужно отформатировать и массив параметров. Вот так рекомендуется регистрировать функции форматирования:
    (function(format)<br/>{<br/>    // Регистрация функции форматирования<br/>    // name   - имя для использования в маркерах<br/>    // v      - значение для форматирования, в функцию будет передано так же, как его передали в функцию format<br/>    // params - массив параметров, всегда есть, но межет быть нулевого размера<br/>    // Функция обязана вернуть строку, которая будет подставлена вместо метки<br/>    format.add(name, function(v, params)<br/>    {<br/>        return ...;<br/>    });<br/>})(String.prototype.format);

    Встроенные функции форматирования

    В скрипте уже встроены функции форматирования для чисел, массивов и дат.

    {0:n} — форматирование числа, если в функцию пришло не число, то будет выведено NaN. Вид чисел 1.11111111e+20 будет преобразован в нормальный: 111111111000000000000. Можно передавать строки с числом: '1.67' или '123.456e+2' — будет вставлено соответственно 1.67 и 12345.6.

    {0:n([i][,f])} — форматирование числа с заполнением нулями до нужного числа разрядов.
    i — количество разрядов для целой части, если в целой части больше разрадов, то они остаются на месте, если меньше — в начале будет вставлено нужное число нулей.
    f — количество разрядов для дробной части, лишние числа будут отброшены.
    Параметры можно пропускать: {0:n(,2)} — вывести число с 2-мя знаками в десятичной части.

    {0:df([f])} — произвольное форматирование даты, f — строка формата с подстановками, возможные подстановки:
    • yy или yyyy — Год, всегда выводится 4 знака.
    • M или MM — Месяц, 1 или 2 знака
    • d или dd — День, 1 или 2 знака
    • H или HH — Часы, 1 или 2 знака в 24-часовом формате
    • m или mm — Минуты, 1 или 2 знака
    • s или ss — Секунды, 1 или 2 знака
    • f...ffff — Миллисекунды, от 1 до 4 знаков

    Более полная документация, где скачать скрипт

    Собственно все есть тут: полное описание встроенных форматов, тестовый скрипт, исходники и упакованная версия

    Скрипт для работы не требует никаких дополнительных библиотек и разбит на 3 части:
    1. Собственно реализация основного кода форматирования
    2. Форматирование чисел
    3. Форматирование даты/времени

    Для уменьшения скрипта можно удалить оттуда вторую и(или) третью части.
    В исходнике достаточно комментариев, что бы понять, как он работает.
    Весь код раскрашен с помощью DmSyntax
    Поделиться публикацией
    Похожие публикации
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 18
    • +1
      • +1
        а не было такого случайно во фреймворке от майкрософта? тот, который добавляется scriptManager'ом? вообще интересная возможность, джаваскрипт все больше сишарпеет (или наоборот?))
        • 0
        • 0
          Я микрософтовский фрейморк не ковырял — ничего сказать не могу. Многие языки уже давно занимаются заимствованиями друг у друга, просто меня и коллег достало в свое время заниматься постоянной самоцензурой и что бы не писать
          var s = 'str'.concat(...);

          или
          var s = ['str', ... ].join('');

          или вообще непотребство
          var s = 'str'+...;
        • +4
          Красиво конечно. Но Клиентское программирование имеет некоторые особенности. Так вот по 4К всякой мелочевки накапливается, а потом люди удивляются — почему все так тормозит?
          • +1
            Клиентское это да, проблема с объемами тут имеет место. Но еще последнее время люди пытаются использовать JS на сервере ( habrahabr.ru/blogs/nginx/82511/, habrahabr.ru/blogs/javascript/27915/, habrahabr.ru/blogs/javascript/71858/, и еще можно тут почитать steve-yegge.blogspot.com/2008/06/rhinos-and-tigers.html ) и тут уже проблем с маленькими, но вкусными механизмами нет т.к. никуда не передается.
            • 0
              А вот серверное применение — это то что мне совсем не понять. По крайней мере на сегодняшнем уровне.
              Jscript для сервера можно было использовать много лет назад в ASP/NET. Но как-то на практике предпочитают предпочитают С++/C# или омерзительнейшим VB.
              • +2
                JS на сервере достаточно удобна как альтернатива точно классифицированному VB. С приходом ASP.NET актуальность на винде сильно потеряна, но вот пытливые умы запускают тот же V8 на стороне сервера и я считаю это отличной альтернативой мутному PHP на *nix платформах.
                • 0
                  Ну очень странная альтернатива :)
          • 0
            Велосипедостроение процветает, товарищи! Как минимум существует вот это:
            api.dojotoolkit.org/jsdoc/1.3.2/dojo.string.substitute
            Думаю, что и в других тулкитах есть что=то подобное.
            Отсуда вопрос — почему не переиспользовать существующий код?
            • 0
              Как мне нравятся такие каменты, ну чистая популистика :).
              Давайте посмотрим так: как я написал в начале топика, тот скрипт, что я опубликовал, используется достаточно давно, на всякий случай уточняю — минимум года как 3, Dojo Toolkit когда появился? Когда была необходимость, естественно был сделан поиск и результаты были плачевными.
              Для использования приведенного вами метода нужно скачать Dojo Toolkit (может даже и не весь, а только ядро+строковые утилиты) и сколько он при этом весит? Опять же опубликованный мной скрипт — «чистый», ему больше ничего не нужно и он может работать даже на сервере.
              И под конец мелочь: substitute из Dojo Toolkit имеет другую нотацию меток и способ передачи параметров, а у меня идет разговор про похожесть на String.Format из C#.
              Уточню на всякий случай: я опубликовал то, что уже у меня было, опробовано и используется коллегами. Судя по скачиваниям и просмотрам это интересно достаточному количеству людей.
              • 0
                >и в других тулкита… почему не переиспользовать существующий код?
                как-то сложилось, что dojo и другие фреймворки оказался на переферии js-велосипедостроения. Поэтому для большинства разработчиков предпочтительнее иметь дело c jQuery
                ЗЫ! я ни в коем случае не сравниваю качество различных велосипедов. Только распространенность запчастей, рем.мостерских и тренеров по езде на этих велосипедах.
                • 0
                  Sorry Офтопик конкретный. Слишком много выпил.
              • 0
                Нашел в исходниках gnome-shell

                pastie.org/811028

                <code>
                "somestring %s %d".format('hello', 5)
                </code>
                • 0
                  Не исключаю, что, для кого-то и удобно может быть. Но не понравилось. Кода много, юнит-тестов нет, форматирование смесью табов и пробелов (при просмотре кода, конечно, уехало все куда-то). Да и лицензия в наш век неприемлемая совершенно: GPL для некоммерческого использования, «свяжитесь со мной для коммерческого». Хоть бы в статье про это написали.
                  • 0
                    Не понравилось, так не понравилось, бывает. Однако если вы не просто прошли мимо, а оставили свое мнение, то хотелось бы задать вопросы по некоторым моментам:
                    1. «Кода много» — много для чего? Там и так код на грани читаемости.
                    2. «юнит-тестов нет» — я их и не хотел выкладывать, однако причесывать код без них тяжеловато было бы, с вашей т.з. их тоже не мешало бы выложить?
                    3. «форматирование смесью табов и пробелов...» — весьма интересное наблюдение, у вас наверно табуляция в редакторе настроена не на 4 символа или свой код вы только пробелами выравниваете? (я пишу по привычным мне и моим коллегам правилам оформления кода и читается он нами без проблем)
                    4. С лицензией я погорячился, согласен. Однако я не большой спец во всем множестве лицензий, какую бы вы посоветовали бы?
                    • 0
                      Думаю, что библиотека сама по себе должна быть хорошая (иначе не возникло бы желания ее выкладывать куда-то, к примеру, или использовать несколько лет). Не понравилось — по разным косвенным причинам, которые как-то помешали даже попробовать.

                      Перед тем, как что-то использовать, всегда ведь хорошо код прочитать и удостовериться, что все работает как нужно и код написан грамотно. А то, что кода довольно много (видимо, и функционала много, но весь ли он имеет отношение к основной задаче?) и то, что не приложены тесты, эту задачу затрудняют. У меня не так часто возникает задача форматирования текста, и обычный "+" вполне справлялся до сих пор, поэтому время, потраченное на разбор исходников, имеет значение. Тесты я бы оставил, т.к. если что пойдет не так (или кто-нибудь захочет что-нибудь дописать или переписать), будет проще разобраться, ну и вообще, удобно, когда они есть.

                      Насчет табуляции — там ведь именно смесь табов и пробелов? Дефолтный фьюер на маке делал таб в 8 пробелов (по стандартну GNU, видать), поэтому все уехало. Да, код выравниваю только пробелами, редактор настроен на то, чтобы он при сохранении табы в пробелы преобразовывал, со стандарта кодирования, принятого в питоне (pep-008) приучился окончательно к этому, избавляет от некоторых проблем.

                      А лицензия зависит от того, что Вы хотите) По ощущениям, большинство библиотек на скриптовых языках выкладываются сейчас под чем-нибудь вроде MIT — там из условий, по сути, только сохранение копирайта в исходном коде, все остальное не запрещается. В эпоху github'ов и bitbucket'ов многие разработчики (и фирмы) как-то перестали париться за то, что кто-то украдет их результат работы, а наоборот, теперь стремятся как можно сильнее расширить круг пользователей продукта, чтобы получать как минимум некоторую известность, обратную связь и сообщения об ошибках, при удачном раскладе еще и доработки в свой проект. К хорошему быстро привыкаешь)

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

                  Самое читаемое