Javascript 使用字符串变量动态创建regexp
假设我想使以下内容可重复使用:Javascript 使用字符串变量动态创建regexp,javascript,regex,Javascript,Regex,假设我想使以下内容可重复使用: function replace_foo(target, replacement) { return target.replace("string_to_replace",replacement); } 我可能会这样做: function replace_foo(target, string_to_replace, replacement) { return target.replace(string_to_replace,replacement);
function replace_foo(target, replacement) {
return target.replace("string_to_replace",replacement);
}
我可能会这样做:
function replace_foo(target, string_to_replace, replacement) {
return target.replace(string_to_replace,replacement);
}
对于字符串文字,这非常简单。但是如果我想在正则表达式上变得更复杂一点呢?例如,假设我想替换所有内容,但string\u to\u replace
。出于本能,我会尝试通过以下方式扩展上述内容:
function replace_foo(target, string_to_replace, replacement) {
return target.replace(/^string_to_replace/,replacement);
}
这似乎不起作用。我的猜测是,它认为string\u to\u replace
是字符串文字,而不是表示字符串的变量。是否可以使用字符串变量动态创建JavaScript正则表达式?如果可能的话,这样的事情会很好:
function replace_foo(target, string_to_replace, replacement) {
var regex = "/^" + string_to_replace + "/";
return target.replace(regex,replacement);
}
有newregexp(string,flags)
其中flags
是g
或i
。所以
'GODzilla'.replace( new RegExp('god', 'i'), '' )
评估为
zilla
是的,你可以
正如其他人所说,使用
newregexp(模式、标志)
来实现这一点。值得注意的是,您将向该构造函数传递字符串文本,因此必须转义每个反斜杠。例如,如果希望正则表达式与反斜杠匹配,则需要说newregexp(“\\\\”)
,而正则表达式文本只需要是/\\/
。根据您打算如何使用它,您应该注意在没有足够的预处理(转义特殊字符等)的情况下将用户输入传递给这样的函数。如果不这样做,您的用户可能会得到一些非常意外的结果
对于字符串文字,这非常简单
不是真的!该示例仅将第一次出现的string\u替换为\u replace
。更常见的是,您希望替换所有引用,在这种情况下,您必须将字符串转换为全局(/…/g
)RegExp。可以使用new RegExp
构造函数从字符串执行此操作:
new RegExp(string_to_replace, 'g')
问题是,字符串文字中的任何正则表达式特殊字符都将以其特殊的方式运行,而不是作为普通字符。你必须用反斜杠避开它们才能解决这个问题。不幸的是,没有内置函数可以为您执行此操作,因此您可以使用以下函数:
function escapeRegExp(s) {
return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
}
还要注意,当您在replace()
中使用RegExp时,替换字符串现在也有一个特殊字符,$
。如果要在替换文本中包含文字$
,则也必须转义此项
function escapeSubstitute(s) {
return s.replace(/\$/g, '$$$$');
}
(四个$
s,因为它本身就是一个替换字符串argh!)
现在,您可以使用RegExp实现全局字符串替换:
function replace_foo(target, string_to_replace, replacement) {
var relit= escapeRegExp(string_to_replace);
var sub= escapeSubstitute(replacement);
var re= new RegExp(relit, 'g');
return target.replace(re, sub);
}
多痛苦啊。幸运的是,如果您只想直接替换字符串,而不需要使用regex的其他部分,那么有一种更快的方法:
s.split(string_to_replace).join(replacement)
…就这些。这是一个通俗易懂的成语
说我想把所有的东西都换掉,但串要换掉
这意味着什么,要替换所有未参与字符串匹配的文本?用^
替换肯定不会改变这一点,因为^
表示字符串标记的开始,而不是否定^
仅在[]
字符组中为否定。也有负面的lookaheads(?!…)
,但是JScript中存在这个问题,所以您通常应该避免它
您可以尝试将“所有内容都匹配到”字符串,并使用函数放弃匹配字符串之间的任何空拉伸:
var re= new RegExp('(.*)($|'+escapeRegExp(string_to_find)+')')
return target.replace(re, function(match) {
return match[1]===''? match[2] : replacement+match[2];
});
在这里,拆分可能更简单:
var parts= target.split(string_to_match);
for (var i= parts.length; i-->0;)
if (parts[i]!=='')
parts[i]= replacement;
return parts.join(string_to_match);
我认为我有一个很好的例子来突出显示字符串中的文本(它发现不看寄存器,而是使用寄存器突出显示) 函数getHighlightedText(基本字符串、过滤器字符串){ 如果((基本字符串==“”)返回基本字符串,则返回基本字符串; 返回basicString.replace(新的RegExp(filterString.replace(/[-\/\\^$*+.()[\]{}]/g,'\\\\$&'),'gi'), 功能(匹配) {return”“+match+”“}); }
解决这个问题的一个非常简单的方法是:
function replace(target, string_to_replace, replacement) {
return target.split(string_to_replace).join(replacement);
}
根本不需要正则表达式
它似乎也是现代浏览器上速度最快的,并且在使用此表单时也省略了
/
正则表达式分隔符。这个答案虽然不是最详细的,但确实提到了一个关键的细节,我刚刚坚持了一个小时:避开任何特殊序列。例如,我正在搜索一个以某个术语开头的单词,因此我需要的正则表达式是/\b[term]\b/
,但在构造它时,我需要调用新的正则表达式(“\\b”+term+“\\b”)
。虽然差异很小但很重要,而且很难发现,因为直接将其作为正则表达式使用确实可以按预期工作。
function getHighlightedText(basicString, filterString) {
if ((basicString === "") || (basicString === null) || (filterString === "") || (filterString === null)) return basicString;
return basicString.replace(new RegExp(filterString.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\\\$&'), 'gi'),
function(match)
{return "<mark>"+match+"</mark>"});
}
function replace(target, string_to_replace, replacement) {
return target.split(string_to_replace).join(replacement);
}