从任意正则表达式创建字符串模板?

时间:2018-10-07 17:23:50

标签: javascript regex string format string-formatting

正则表达式用于解析已格式化的字符串,但我想使用它们来提取原始字符串并格式化它们,例如:

palindrome
// phone number
format("\(\d{3}\) \d{3}-\d{4}", "1234567890");
// should return "(123) 456-7890"
// date
format("\d{4}-\d{2}-\d{2}", "20180712");
// should return "2018-07-12"

上面是例子我想要一个适用于任何正则表达式和任意字符串(适合正则表达式)的通用解决方案。

>

这是我到目前为止所拥有的,虽然有点不雅致,但功能确实很有限,但确实满足了上面三个示例中的前两个:

// arbitrary
format("([A-Z]+-\d+ )+", "ABC123DEFGH45IJ6789");
// should return "ABC-123 DEFGH-45 IJ-6789 "

以上解决方案可以扩展到更复杂的正则表达式吗?还是有更好的替代方法?

2 个答案:

答案 0 :(得分:2)

通常的答案是:使用创建groups的正则表达式,然后将replace与反向引用一起使用以格式化输出。

例如,使用第一个示例,请使用以下正则表达式:

/(\d{3})(\d{3})(\d{4})/

它将创建三个组,前三个数字,后三个数字和最后四个数字。

现在使用以下替换模式,使用string.replace函数:

($1) $2-$3

我将在第一个组周围添加括号,在其后添加第二个组,最后一个连字符和最后一个组。

使用方法:

您可以这样创建formatPhone函数:

function formatPhone(rawPhone)
{
    return rawPhone.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
}

您可以使用其他模式进行类似操作。

修改

一个完全笼统的灵魂要求您将原始字符串,正则表达式模式和替换模式都传递给函数,如下所示:

function format(rawString, regex, replacement)
{
   return rawString.replace(regex, replacement);
}

正则表达式和替换必须遵循上述规则。

Edit2

我认为您在这里误解了一些信息。让我们以第一个示例为例:

format("\(\d{3}\) \d{3}-\d{4}", "1234567890");

这里正则表达式完全不匹配 !!!简而言之,您不能创建使用格式正则表达式的函数。如上所示,对match(可能还有replace)进行了正则表达式。

答案 1 :(得分:1)

您可以使用模式(\d{3})(\d{3})(\d{4})并将其替换为(\d{3})(\d{3})(\d{4}),从而产生123-456-7890

对于第三个示例,使用:(\w{3})(\w{3})(\w{5})(\w{2})(\w{2})(\w{4})并将其替换为\1-\2 \3-\4 \5-\6,它返回ABC-123 DEFGH-45 IJ-6789

通常使用(\w{n})...(\w{m}),其中nm是一些整数,用于将字符串的p [arts]捕获到特定的组(您可以使用数组指定这些整数)。您还可以在数组中提供分隔符以形成图案。

Demo

更新

正如我所说,一般的解决方案是提供块的大小,该字符串应分为分隔符和数组。参见下面的代码:

var str =  "ABC123DEFGH45IJ6789";
var blockSizes = [3,3,5,2,2,4];
var separators = ["-"," ","-"," ","-"];
var pattern = "(\\w{" + blockSizes[0] + "})";
var replacementPattern = "$1";
var i;
for(i = 1; i < blockSizes.length; i++)
{
    pattern += "(\\w{" + blockSizes[i] + "})";
    replacementPattern += separators[i - 1] + "$" + (i + 1);
}

现在,只需使用以下模式进行替换就可以了:

JS fiddle

Regex demo