#javascript #regex
#javascript #регулярное выражение
Вопрос:
хотите избежать всех вхождений «.» и «:» в квадратных скобках
[ab:1.2:ef]='12.3' => [ab:1.2:ef]='12.3'
пробовал различные перестановки replace
, например,
str.replace( /([.*)(.|:)(.*])/g, '1\23' );
но никакой радости.
Оба ответа правильные и не только.
Первое, чистое совпадение с шаблоном, выполняет свою работу и является очень кратким. На мой взгляд, это лучше отвечает на поставленный вопрос.
Второй, вызываемый replace
с помощью функции arg, немного более надежный и предлагает значительно большую гибкость. В моем коде используется этот подход, потому что он легко обрабатывает пару особых случаев.
Ответ №1:
Предполагая, что скобки всегда правильно сбалансированы (даже в строках или комментариях) и никогда не могут быть вложенными или экранированными, вы можете решить это в одном регулярном выражении, используя предварительные утверждения:
result = subject.replace(/([:.])(?=[^[]]*])/g, "\$1");
В качестве прокомментированного регулярного выражения:
([:.]) # Match and remember a dot/colon,
(?= # only if it is followed by:
[^[]]* # any number of characters excluding brackets,
] # followed by a closing bracket.
) # End of lookahead assertion.
Предварительный просмотр гарантирует, что следующая скобка после точки / двоеточия, на которую мы смотрим, является закрывающей скобкой.
Комментарии:
1. отличное объяснение. меня удивило, что вы не беспокоитесь о начальной скобке (поскольку она должна быть там) — делает сопоставление менее сложным.
2. Это не требует как открывающей, так и закрывающей фигурной скобки. Таким образом, это не работает для:
[ab:1.2:ef]='12.3]'
илиab:1.2:ef]='12.3'
.3. Правильно, вот почему я написал, что скобки должны быть правильно сбалансированы (JavaScript не поддерживает утверждения lookbehind). Я должен добавить, что это также касается скобок внутри строк, комментариев и т. Д.
Ответ №2:
Я знаю только, как это сделать с помощью функции replace:
var test = "[ab:1.2:ef]='12.3'";
var out = test.replace(/[.*?]/g, function(str) {
return(str.replace(/.|:/g, "\$amp;"));
});
// out is [ab:1.2:ef]='12.3'
Посмотрите это в действии здесь: http://jsfiddle.net/jfriend00/ZHVjW /
Комментарии:
1. вау! никогда не видел функцию, используемую в качестве аргумента в
replace
— очень круто. намного элегантнее, чемmatch
цикл, который использовался ранее. Спасибо!2. Что касается вашего комментария к моему ответу, у вашего регулярного выражения также будут проблемы с несбалансированными скобками в строках, подобных
[ab:1.2] = '[12.3'; [cd:3.4] = '34.5]'
. Как только разделители не сбалансированы и / или внутри строк / комментариев, регулярные выражения начинают завершаться сбоем, и для такой работы вам нужен синтаксический анализатор.3. Да, тонкая грань между выполнением работы и выводом большого железа. Тем не менее, знаете ли вы утилиту, которая преобразует (несколько) произвольную строку в древовидную структуру польского типа?
4. @TimPietzcker — пример, на который вы указываете, — это вложенные скобки. В OP не указано, что вложенные скобки являются обязательным требованием. Решение для вложенных было бы намного сложнее (вероятно, не просто проблема с регулярными выражениями) при любом подходе. Мне просто показалось странным, что ваше решение не требует какой-либо открытой скобки. Если с этим все в порядке, ничего страшного.
5. Какие вложенные скобки? Это было бы дополнительной проблемой (для всех наших регулярных выражений); здесь внутри строк просто скобки. Проблема осталась бы идентичной
[ab:1.2] = '[12.3'; [cd:3.4] = '34.5'
.