Вы можете использовать эту функцию
String.prototype.format = function (args) {
var str = this;
return str.replace(String.prototype.format.regex, function(item) {
var intVal = parseInt(item.substring(1, item.length - 1));
var replace;
if (intVal >= 0) {
replace = args[intVal];
} else if (intVal === -1) {
replace = "{";
} else if (intVal === -2) {
replace = "}";
} else {
replace = "";
}
return replace;
});
};
String.prototype.format.regex = new RegExp("{-?[0-9]+}", "g");
// Sample usage.
var str = "She {1} {0}{2} by the {0}{3}. {-1}^_^{-2}";
str = str.format(["sea", "sells", "shells", "shore"]);
alert(str);
(Это длиннее, чем я предполагал; пожалуйста, будьте терпеливы.)
Большинство языков состоит из того, что называется "синтаксисом": язык состоит из нескольких четко определенных ключевых слов , и полный набор выражений, которые вы можете построить на этом языке, создается на основе этого синтаксиса.
Например, предположим, что у вас есть простой арифметический «язык» с четырьмя функциями, который принимает только однозначные целые числа в качестве входных и полностью игнорирует порядок операций (я сказал вам, что это был простой язык). Этот язык можно определить с помощью синтаксиса:
// The | means "or" and the := represents definition
$expression := $number | $expression $operator $expression
$number := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
$operator := + | - | * | /
Из этих трех правил вы можете построить любое количество арифметических выражений с вводом одной цифры. Затем вы можете написать синтаксический анализатор для этого синтаксиса, который разбивает любой допустимый ввод на его типы компонентов ( $ expression
, $ number
, или $ operator
) и обрабатывает результат. Например, выражение 3 + 4 * 5
может быть разбито следующим образом:
// Parentheses used for ease of explanation; they have no true syntactical meaning
$expression = 3 + 4 * 5
= $expression $operator (4 * 5) // Expand into $exp $op $exp
= $number $operator $expression // Rewrite: $exp -> $num
= $number $operator $expression $operator $expression // Expand again
= $number $operator $number $operator $number // Rewrite again
Теперь у нас есть полностью проанализированный синтаксис на нашем определенном языке для исходного выражения. Когда у нас есть это, мы можем пройти и написать синтаксический анализатор, чтобы найти результаты всех комбинаций $ number $ operator $ number
, и выдать результат, когда у нас есть только одно $ number
слева.
Обратите внимание, что в окончательной проанализированной версии нашего исходного выражения не осталось конструкций $ expression
. Это потому, что $ expression
всегда можно свести к комбинации других вещей в нашем языке.
PHP во многом такой же: языковые конструкции распознаются как эквивалент нашего $ number
или $ operator
. Их нельзя свести к другим языковым конструкциям ; вместо этого они являются базовыми единицами, из которых строится язык. Ключевое различие между функциями и языковыми конструкциями заключается в следующем: синтаксический анализатор имеет дело непосредственно с языковыми конструкциями. Он упрощает функции в языковых конструкциях.
Причина, по которой языковые конструкции могут требовать или не требовать круглых скобок, и причина, по которой одни имеют возвращаемые значения, а другие нет, полностью зависит от конкретных технических деталей реализации синтаксического анализатора PHP. Я не очень разбираюсь в том, как работает парсер, поэтому не могу конкретно ответить на эти вопросы, но представьте на секунду язык, который начинается со следующего:
$expression := ($expression) | ...
Фактически, этот язык может свободно принимать любые найденные выражения и избавляться от окружающих скобок. PHP (и здесь я использую чистые догадки) может использовать нечто подобное для своих языковых конструкций: print ("Hello")
может быть сокращено до print "Hello"
перед тем, как его проанализировать или наоборот (определения языков могут добавлять круглые скобки, а также избавляться от них).
Это корень того, почему вы не можете переопределить языковые конструкции, такие как echo
или print
: они фактически жестко запрограммированы в синтаксическом анализаторе, тогда как функции отображаются на набор языковых конструкций, а синтаксический анализатор позволяет вам изменить это отображение во время компиляции или выполнения, чтобы заменить ваш собственный набор языковых конструкций или выражений.
В конце дня, внутреннее различие между конструкциями и выражениями заключается в следующем: языковые конструкции понимаются и обрабатываются синтаксическим анализатором. Встроенные функции, хотя и предоставляются языком, отображаются и упрощаются в набор языковых конструкций перед синтаксическим анализом.
Дополнительная информация:
Изменить: Читая некоторые другие ответы, люди делают хорошие выводы. Среди них:
Языковые конструкции предоставляются самим языком ( как инструкции типа «если», «пока», ...); отсюда и их название.
Одним из следствий этого является то, что они быстрее вызываются, чем предопределенные или определяемые пользователем функции (по крайней мере, я слышал / читал несколько раз)
Я понятия не имею, как это сделано, но одна вещь, которую они могут сделать (из-за того, что они интегрированы непосредственно в язык), - это «обойти» какой-то механизм обработки ошибок. Например, isset () может использоваться с несуществующими переменными без каких-либо уведомлений, предупреждений или ошибок.
function test($param) {}
if (test($a)) {
// Notice: Undefined variable: a
}
if (isset($b)) {
// No notice
}
* Обратите внимание, что это не относится к конструкциям всех языков.
Еще одно различие между функциями и языковыми конструкциями заключается в том, что некоторые из них могут вызываться без скобок, как ключевое слово.
Например:
echo 'test'; // language construct => OK
function my_function($param) {}
my_function 'test'; // function => Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING
Здесь тоже не все языковые конструкции.
I предположим, что нет абсолютно никакого способа "отключить" языковую конструкцию, потому что она является частью самого языка. С другой стороны, многие «встроенные» функции PHP на самом деле не встроены, потому что они предоставляются расширениями, так что они всегда активны (но не все из них)
Еще одно отличие заключается в том, что язык конструкции не могут использоваться как "указатели функций" (я имею в виду, например, обратные вызовы):
$a = array(10, 20);
function test($param) {echo $param . '<br />';}
array_map('test', $a); // OK (function)
array_map('echo', $a); // Warning: array_map() expects parameter 1 to be a valid callback, function 'echo' not found or invalid function name
У меня сейчас нет другой идеи ... и я мало знаю о внутренности PHP ... Так что ' Будет это прямо сейчас ^^
Если вы не получите здесь много ответов, возможно, вы могли бы спросить об этом во внутренней части списка рассылки (см. http: //www.php. net / mailing-lists.php ), где есть много разработчиков ядра PHP; это те, кто, вероятно, знают об этом ^^
(И меня действительно интересуют другие ответы, кстати ^^)
В качестве справки: список ключевых слов и языковых конструкций в PHP
Вы можете переопределить встроенные функции . Ключевые слова навсегда.
Пройдя по коду, я обнаружил, что php разбирает некоторые инструкции в файле yacc. Так что это особые случаи.
(см. Zend / zend_language_parser.y)
Кроме этого, я не думаю, что есть другие различия.