Подтвердить что ты не робот

Использование String.Format в JavaScript?

Это сводит меня с ума. По-моему, я задал этот один и тот же вопрос, но больше не могу его найти (я использовал Stack Поиск переполнения, Google Поиск, вручную просмотрел мои сообщения и искал мой код).

Мне нужно что-то, что было бы похоже на С# String.Format, где вы могли бы сделать что-то вроде

string format = String.Format("Hi {0}",name);

для JavaScript, конечно, и один человек дал мне простой ответ: он не был похож на плагин jQuery или что-то еще, но я думаю, что вы сделали кое-что JSON или что-то в этом роде, и он работал и был прост в использовании.

Я за жизнь меня не могу найти этот пост.

У меня есть это в моем коде, но я не могу найти ничего, что его использует, и я уверен, что использовал его пару раз:

String.prototype.format = function(o)
{
    return this.replace(/{([^{}]*)}/g,
       function(a, b)
       {
           var r = o[b];
           return typeof r === 'string' ? r : a;
       }
    );
};
4b9b3361

Ответ 1

Адаптируйте код из Строка MsAjax.

Просто удалите весь код _validateParams, и вы больше всего на пути к полноценному классу строк .NET в JavaScript.

Хорошо, я освободил класс строки msajax, удалив все зависимости msajax. Он отлично работает, как и класс .NET string, включая функции trim, endsWith/startsWith и т.д.

P.S. - Я оставил все помощники Visual Studio JavaScript IntelliSense и XmlDocs на месте. Они безобидны, если вы не используете Visual Studio, но можете удалить их, если хотите.

<script src="script/string.js" type="text/javascript"></script>
<script type="text/javascript">
    var a = String.format("Hello {0}!", "world");
    alert(a);

</script>

String.js

// String.js - liberated from MicrosoftAjax.js on 03/28/10 by Sky Sanders
// permalink: http://stackoverflow.com/a/2534834/2343

/*
    Copyright (c) 2009, CodePlex Foundation
    All rights reserved.

    Redistribution and use in source and binary forms, with or without modification, are permitted
    provided that the following conditions are met:

    *   Redistributions of source code must retain the above copyright notice, this list of conditions
        and the following disclaimer.

    *   Redistributions in binary form must reproduce the above copyright notice, this list of conditions
        and the following disclaimer in the documentation and/or other materials provided with the distribution.

    *   Neither the name of CodePlex Foundation nor the names of its contributors may be used to endorse or
        promote products derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED
    WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
    IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</textarea>
*/

(function(window) {

    $type = String;
    $type.__typeName = 'String';
    $type.__class = true;

    $prototype = $type.prototype;
    $prototype.endsWith = function String$endsWith(suffix) {
        /// <summary>Determines whether the end of this instance matches the specified string.</summary>
        /// <param name="suffix" type="String">A string to compare to.</param>
        /// <returns type="Boolean">true if suffix matches the end of this instance; otherwise, false.</returns>
        return (this.substr(this.length - suffix.length) === suffix);
    }

    $prototype.startsWith = function String$startsWith(prefix) {
        /// <summary >Determines whether the beginning of this instance matches the specified string.</summary>
        /// <param name="prefix" type="String">The String to compare.</param>
        /// <returns type="Boolean">true if prefix matches the beginning of this string; otherwise, false.</returns>
        return (this.substr(0, prefix.length) === prefix);
    }

    $prototype.trim = function String$trim() {
        /// <summary >Removes all leading and trailing white-space characters from the current String object.</summary>
        /// <returns type="String">The string that remains after all white-space characters are removed from the start and end of the current String object.</returns>
        return this.replace(/^\s+|\s+$/g, '');
    }

    $prototype.trimEnd = function String$trimEnd() {
        /// <summary >Removes all trailing white spaces from the current String object.</summary>
        /// <returns type="String">The string that remains after all white-space characters are removed from the end of the current String object.</returns>
        return this.replace(/\s+$/, '');
    }

    $prototype.trimStart = function String$trimStart() {
        /// <summary >Removes all leading white spaces from the current String object.</summary>
        /// <returns type="String">The string that remains after all white-space characters are removed from the start of the current String object.</returns>
        return this.replace(/^\s+/, '');
    }

    $type.format = function String$format(format, args) {
        /// <summary>Replaces the format items in a specified String with the text equivalents of the values of   corresponding object instances. The invariant culture will be used to format dates and numbers.</summary>
        /// <param name="format" type="String">A format string.</param>
        /// <param name="args" parameterArray="true" mayBeNull="true">The objects to format.</param>
        /// <returns type="String">A copy of format in which the format items have been replaced by the   string equivalent of the corresponding instances of object arguments.</returns>
        return String._toFormattedString(false, arguments);
    }

    $type._toFormattedString = function String$_toFormattedString(useLocale, args) {
        var result = '';
        var format = args[0];

        for (var i = 0; ; ) {
            // Find the next opening or closing brace
            var open = format.indexOf('{', i);
            var close = format.indexOf('}', i);
            if ((open < 0) && (close < 0)) {
                // Not found: copy the end of the string and break
                result += format.slice(i);
                break;
            }
            if ((close > 0) && ((close < open) || (open < 0))) {

                if (format.charAt(close + 1) !== '}') {
                    throw new Error('format stringFormatBraceMismatch');
                }

                result += format.slice(i, close + 1);
                i = close + 2;
                continue;
            }

            // Copy the string before the brace
            result += format.slice(i, open);
            i = open + 1;

            // Check for double braces (which display as one and are not arguments)
            if (format.charAt(i) === '{') {
                result += '{';
                i++;
                continue;
            }

            if (close < 0) throw new Error('format stringFormatBraceMismatch');


            // Find the closing brace

            // Get the string between the braces, and split it around the ':' (if any)
            var brace = format.substring(i, close);
            var colonIndex = brace.indexOf(':');
            var argNumber = parseInt((colonIndex < 0) ? brace : brace.substring(0, colonIndex), 10) + 1;

            if (isNaN(argNumber)) throw new Error('format stringFormatInvalid');

            var argFormat = (colonIndex < 0) ? '' : brace.substring(colonIndex + 1);

            var arg = args[argNumber];
            if (typeof (arg) === "undefined" || arg === null) {
                arg = '';
            }

            // If it has a toFormattedString method, call it.  Otherwise, call toString()
            if (arg.toFormattedString) {
                result += arg.toFormattedString(argFormat);
            }
            else if (useLocale && arg.localeFormat) {
                result += arg.localeFormat(argFormat);
            }
            else if (arg.format) {
                result += arg.format(argFormat);
            }
            else
                result += arg.toString();

            i = close + 1;
        }

        return result;
    }

})(window);

Ответ 2

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

  String.format = function() {
      var s = arguments[0];
      for (var i = 0; i < arguments.length - 1; i++) {       
          var reg = new RegExp("\\{" + i + "\\}", "gm");             
          s = s.replace(reg, arguments[i + 1]);
      }
      return s;
  }

И я называю это так:

var greeting = String.format("Hi, {0}", name);

Я не помню, где я нашел это, но это было очень полезно для меня. Мне это нравится, потому что синтаксис такой же, как и версия С#.

Ответ 3

Вы можете сделать серию замещений:

function format(str)
{
    for(i = 1; i < arguments.length; i++)
    {
        str = str.replace('{' + (i - 1) + '}', arguments[i]);
    }
    return str;
}

Лучшим подходом будет использование функции замены:

function format(str, obj) {
    return str.replace(/\{\s*([^}\s]+)\s*\}/g, function(m, p1, offset, string) {
        return obj[p1]
    })
}

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

var arr = ['0000', '1111', '2222']

arr.a = 'aaaa'

str = format(" { 0 } , {1}, { 2}, {a}", arr)
// returns 0000 , 1111, 2222, aaaa

Ответ 4

Вот полезная функция форматирования строк с использованием регулярных выражений и захватов:

function format (fmtstr) {
  var args = Array.prototype.slice.call(arguments, 1);
  return fmtstr.replace(/\{(\d+)\}/g, function (match, index) {
    return args[index];
  });
}

Строки могут быть отформатированы как С# String.Format:

var str = format('{0}, {1}!', 'Hello', 'world');
console.log(str); // prints "Hello, world!"

формат будет помещать правильную переменную в нужное место, даже если они выглядят не по порядку:

var str = format('{1}, {0}!', 'Hello', 'world');
console.log(str); // prints "world, Hello!"

Надеюсь, это поможет!

Ответ 5

Без функции третьей стороны:

string format = "Hi {0}".replace('{0}', name)

С несколькими параметрами:

string format = "Hi {0} {1}".replace('{0}', name).replace('{1}', lastname)

Ответ 6

На основе ответа @roydukkey, немного более оптимизированного для времени выполнения (он кэширует регулярные выражения):

(function () {
    if (!String.prototype.format) {
        var regexes = {};
        String.prototype.format = function (parameters) {
            for (var formatMessage = this, args = arguments, i = args.length; --i >= 0;)
                formatMessage = formatMessage.replace(regexes[i] || (regexes[i] = RegExp("\\{" + (i) + "\\}", "gm")), args[i]);
            return formatMessage;
        };
        if (!String.format) {
            String.format = function (formatMessage, params) {
                for (var args = arguments, i = args.length; --i;)
                    formatMessage = formatMessage.replace(regexes[i - 1] || (regexes[i - 1] = RegExp("\\{" + (i - 1) + "\\}", "gm")), args[i]);
                return formatMessage;
            };
        }
    }
})();

Ответ 8

Просто выполните и используйте эту функцию:

function format(str, args) {
   for (i = 0; i < args.length; i++)
      str = str.replace("{" + i + "}", args[i]);
   return str;
}

Если вы не хотите изменять параметр str, то перед циклом for клонируйте (дублируйте) его на новую строку (создайте новую копию str) и установите копию в цикле for и, наконец, верните ее вместо самого параметра.

В С# (Sharp) просто создать копию, просто позвонив String.Clone(), но я не знаю, как в JavaScript, но вы можете искать в Google или заниматься серфингом в Интернете и узнавать, как это сделать.

Я просто дал вам представление о строчном формате в JavaScript.

Ответ 9

Здесь решение, которое работает только с String.prototype:

String.prototype.format = function() {
    var s = this;
    for (var i = 0; i < arguments.length; i++) {       
        var reg = new RegExp("\\{" + i + "\\}", "gm");             
        s = s.replace(reg, arguments[i]);
    }
    return s;
}

Ответ 10

Используйте литерал шаблона в ECMAScript 6:

var customer = { name: "Foo" }
var card = { amount: 7, product: "Bar", unitprice: 42 }
var message = `Hello ${customer.name},
               want to buy ${card.amount} ${card.product} for
               a total of ${card.amount * card.unitprice} bucks?`

Ответ 11

Помимо того, что вы модифицируете прототип String, нет ничего плохого в функции, которую вы предоставили. Способ, которым вы его используете, заключается в следующем:

"Hello {0},".format(["Bob"]);

Если вы хотите, чтобы это была автономная функция, вы можете немного ее изменить:

function format(string, object) {
    return string.replace(/{([^{}]*)}/g,
       function(match, group_match)
       {
           var data = object[group_match];
           return typeof data === 'string' ? data : match;
       }
    );
}

Метод Витторе также хорош; его функция вызывается с каждой передаваемой опцией форматирования в качестве аргумента, в то время как ваш ожидает объект.

На самом деле это выглядит так: John Resig микро-templating engine.

Ответ 12

Ваша функция уже принимает объект JSON в качестве параметра:

string format = "Hi {foo}".replace({
    "foo": "bar",
    "fizz": "buzz"
});

если вы заметили, код:

var r = o[b];

просматривает ваш параметр (o) и использует пары ключ-значение внутри него для разрешения "заменить"

Ответ 13

Вот решение, которое позволяет использовать как прототипы, так и функции.

// --------------------------------------------------------------------
// Add prototype for 'String.format' which is c# equivalent
//
// String.format("{0} i{2}a night{1}", "This", "mare", "s ");
// "{0} i{2}a night{1}".format("This", "mare", "s ");
// --------------------------------------------------------------------

if(!String.format)
    String.format = function(){
        for (var i = 0, args = arguments; i < args.length - 1; i++)
            args[0] = args[0].replace("{" + i + "}", args[i + 1]);
        return args[0];
    };
if(!String.prototype.format && String.format)
    String.prototype.format = function(){
        var args = Array.prototype.slice.call(arguments).reverse();
        args.push(this);
        return String.format.apply(this, args.reverse())
    };

Enjoy.

Ответ 14

Я только начал переносить Java String.format() на JavaScript. Возможно, вам это тоже будет полезно.

Он поддерживает такие основные вещи, как это:

StringFormat.format("Hi %s, I like %s", ["Rob", "icecream"]);

В результате получается

Hi Rob, I like icecream.

Но также более продвинутое числовое форматирование и форматирование даты, например:

StringFormat.format("Duke Birthday: %1$tA %1$te %1$tB, %1$tY", [new Date("2014-12-16")]);

Duke Birthday: Tuesday 16 December, 2014

Подробнее см. в примерах.

Смотрите здесь: https://github.com/RobAu/javascript.string.format

Ответ 15

if (!String.prototype.format) {
    String.prototype.format = function () {
        var args = arguments;
        return this.replace(/{(\d+)}/g, function (match, number) {
            return typeof args[number] != 'undefined'
              ? args[number]
              : match
            ;
        });
    };
}

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

'{0}-{1}'.format('a','b');
// Result: 'a-b'

JSFiddle

Ответ 17

Вот мои два цента:

function stringFormat(str) {
  if (str !== undefined && str !== null) {
    str = String(str);
    if (str.trim() !== "") {
      var args = arguments;
      return str.replace(/(\{[^}]+\})/g, function(match) {
        var n = +match.slice(1, -1);
        if (n >= 0 && n < args.length - 1) {
          var a = args[n + 1];
          return (a !== undefined && a !== null) ? String(a) : "";
        }
        return match;
      });
    }
  }
  return "";
}

alert(stringFormat("{1}, {0}. You're looking {2} today.",
  "Dave", "Hello", Math.random() > 0.5 ? "well" : "good"));

Ответ 18

//Add "format" method to the string class
//supports:  "Welcome {0}. You are the first person named {0}".format("David");
//       and "First Name:{} Last name:{}".format("David","Wazy");
//       and "Value:{} size:{0} shape:{1} weight:{}".format(value, size, shape, weight)
String.prototype.format = function () {
    var content = this;
    for (var i = 0; i < arguments.length; i++) {
        var target = '{' + i + '}';
        content=content.split(target).join(String(arguments[i]))
        content = content.replace("{}", String(arguments[i]));
    }
    return content;
}
alert("I {} this is what {2} want and {} works for {2}!".format("hope","it","you"))

С помощью этой функции вы можете смешивать и сопоставлять с помощью позиционных и "названных" мест замены.