-1

I am trying to create a regular expression with a character class that has a specific quantifier which is a variable for example:

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

This works as follows (without a variable):

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

However it does not have the same functionality with a quoted pattern instead of a slash-delimited pattern as follows:

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"

edit: to be more clear I have added a summary question which was answered below: How do I create a regular expression with an interpolated variable from a quoted string?

Although my preference would be to use interpolation, it seems that is not available (at least in this context), and is not necessary.

I have also tried to come up with a way to concatenate/join some regex literals to achieve the same result, but have been unable to do so for this use case.

As a side note - I am familiar with this type of regular expression in perl:

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

Which can be made useful as follows:

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"

With the suggestions/answers provided I have created a sample currency string prototype as follows:

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"
Community
  • 1
  • 1
your friend
  • 1
  • 1
  • 3

3 Answers3

0

In JavaScript, you can't concatenate or interpolate into regex literals, but you can create a regex from a string by using the RegExp constructor:

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

Note, by the way, that this:

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

has no effect, because replace doesn't modify a string, but rather, it returns a copy of the string with the replacements made. So you need to write this:

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

instead.

ruakh
  • 175,680
  • 26
  • 273
  • 307
0

There are two problems with this statement:

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

The first is that you are passing a string and not a regular expression object, and the second is that within a string literal the backslash has a special meaning to escape certain things (e.g., "\n" is a newline) so to have an actual backslash in your string literal you need to double it as "\\". Using the RegExp() constructor to create a regex object from a string you get this:

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

So from there you can do this:

var quantifier = 3
str = str.replace(new RegExp("(\\d)(\\d{" + quantifier + "}\\.)"),"$1,$2");
nnnnnn
  • 147,572
  • 30
  • 200
  • 241
0

You can create a RegExp object:

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

str2 would contain 1,23-4.00.

Working example:

Note that you need to escape \ in strings, thus \\.

Hope this helps.

icyrock.com
  • 27,952
  • 4
  • 66
  • 85