Регулярное выражение JavaScript с переменной квантификатора класса символов

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

var str = "1234.00";
var quantifier = 3;
str = str.replace(/(\d)(\d{quantifier}\.)/,"$1,$2");
//str should be "1,234.00"

Это работает следующим образом (без переменной):

var str = "1234.00";
str = str.replace(/(\d)(\d{3}\.)/,"$1,$2");
//str == "1,234.00"

Однако он не имеет такой же функциональности с шаблоном в кавычках вместо шаблона, разделенного косой чертой следующим образом:

var str = "1234.00";
str = str.replace("(\d)(\d{3}\.)","$1,$2");
//str == "1234.00" - not "1,234.00"
//quote symbol choice does not change this
str = str.replace('(\d)(\d{3}\.)',"$1,$2");
//str == "1234.00" - not "1,234.00"

редактировать: чтобы быть более ясным, я добавил итоговый вопрос, на который был дан ответ ниже: Как мне создать регулярное выражение с интерполированной переменной из строки в кавычках?

Хотя я бы предпочел использовать интерполяцию, кажется, что она недоступна (по крайней мере, в этом контексте) и не нужна.

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

В качестве примечания - я знаком с этим типом регулярных выражений в Perl:

my $str = "1234.00";
my $quantifier = 3;
$str =~ s/(\d)(\d{$quantifier}\.)/$1,$2/;
# $str eq "1,234.00"

Что можно сделать полезным следующим образом:

my $str = "1234567890.00";
for my $quantifier (qw(9 6 3)) {
    $str =~ s/(\d)(\d{$quantifier}\.)/$1,$2/;
}
# $str eq "1,234,567,890.00"

С учетом предоставленных предложений и ответов я создал образец строки валюты следующим образом:

String.prototype.toCurrency = function() {
    var copy = parseFloat(this).toFixed(2);
    for (var times = parseInt(copy.length/3); times > 0; times--) {
        var digits = times * 3;
        var re = new RegExp("(\\d)(\\d{" + digits + "}\\.)");
        copy = copy.replace(re,"$1,$2");
    }
    return '$'+copy;
};
str = "1234567890";
str.toCurrency();
// returns "$1,234,567,890.00"

person your friend    schedule 24.02.2012    source источник
comment
Второй вопрос, на который вы ссылаетесь, в основном содержит ответ, который вы ищете.   -  person Felix Kling    schedule 24.02.2012


Ответы (3)


В этом утверждении есть две проблемы:

str.replace("(\d)(\d{3}\.)","$1,$2");

Во-первых, вы передаете строку, а не объект регулярного выражения, а во-вторых, в строковом литерале обратная косая черта имеет особое значение для экранирования определенных вещей (например, "\n" — это новая строка), чтобы иметь фактическую обратную косую черту в ваш строковый литерал, вам нужно удвоить его как "\\". Используя конструктор RegExp() для создания объекта регулярного выражения из строки, вы получите следующее:

str.replace(new RegExp("(\\d)(\\d{3}\\.)"),"$1,$2");

Итак, оттуда вы можете сделать это:

var quantifier = 3
str = str.replace(new RegExp("(\\d)(\\d{" + quantifier + "}\\.)"),"$1,$2");
person nnnnnn    schedule 24.02.2012
comment
Спасибо за разъяснение строки и объекта регулярного выражения - если бы я мог, я бы проголосовал. - person your friend; 24.02.2012

В JavaScript вы не можете конкатенировать или интерполировать литералы регулярных выражений, но вы можете создать регулярное выражение из строки с помощью конструктор RegExp:

str = str.replace(new RegExp('(\\d)(\\d{' + quantifier + '}\\.'), "$1,$2");

Заметьте, кстати, что это:

str.replace(..., ...);

не имеет никакого эффекта, потому что replace не изменяет строку, а возвращает копию строки с произведенными заменами. Итак, вам нужно написать это:

str = str.replace(..., ...);

вместо.

person ruakh    schedule 24.02.2012
comment
Отредактировано выше, чтобы использовать оператор присваивания. - person your friend; 24.02.2012

Вы можете создать объект RegExp:

var str = "1234.00";
var digits = 2;
var re = new RegExp("(\\d)(\\d{" + digits + "})");
var str2 = str.replace(re,"$1,$2-");

str2 будет содержать 1,23-4.00.

Рабочий пример:

Обратите внимание, что вам нужно экранировать \ в строках, таким образом, \\.

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

person icyrock.com    schedule 24.02.2012
comment
Спасибо, что предложили экранировать символ \. Это было то, что мне было нужно. - person your friend; 24.02.2012