Javascript 字符串regex replace/prepend
我需要将一个字符串从用户输入转换为搜索栏,这样我就可以在字符串中的任何单词前面加上“contactTags:”这不是一个特殊的搜索字符,比如(,),和,或者,不是搜索输入Javascript 字符串regex replace/prepend,javascript,regex,algolia,Javascript,Regex,Algolia,我需要将一个字符串从用户输入转换为搜索栏,这样我就可以在字符串中的任何单词前面加上“contactTags:”这不是一个特殊的搜索字符,比如(,),和,或者,不是搜索输入(foo或bar)和baz NOT buz变成(contactTags:foo或contactTags:bar)和contactTags:baz非contactTags:buz 该字符串的最终用例是插入到algolia搜索的filters参数中。(但实际上,这个问题更多的是关于正则表达式字符串的替换) 我可以生成一个正则表达式模
(foo或bar)和baz NOT buz
变成(contactTags:foo或contactTags:bar)和contactTags:baz非contactTags:buz
该字符串的最终用例是插入到algolia搜索的filters参数中。(但实际上,这个问题更多的是关于正则表达式字符串的替换)
我可以生成一个正则表达式模式来接近它,但我在字符串替换方面遇到了问题:
const regex = /(?!OR|AND|NOT)\b[\w+]+\b/g;
let str = '(foo OR bar) AND baz NOT buz';
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach(match => {
str = str.replace(/(?!OR|AND|NOT)\b[\w+]+\b/,"contactTags:"+match)
});
}
console.log(str)
不幸的是,这让我的火车失事了:“(contactTags:foo:foo:foo:foo:X10000或bar)而baz不是buz”
有什么想法吗
谢谢 您无需调用
exec
进行替换。只需调用。按如下方式替换:
const regex=/\b(?)(?:或|和| NOT)\b)\w+\b/ig;
让str='(foo或bar)和baz而不是buz';
str=str.replace(regex,'contactTags:$&');
console.log(str)代码>+1哇,我不知道你能做那个美元符号、符号和符号的事,超级酷!我会使用一个函数,但这太酷了@joetom—$&
是一个表示组0的匹配变量,即整个匹配。但是使用它并不是一个好主意,因为它会给替换增加多个X开销。如果是一次性的,则可以,否则在正则表达式/(?!或|和| NOT)\b(\w+)\b/
中指定一个捕获组,并在替换中使用$1
引用它。很漂亮!谢谢大家。你们是从哪里想到零宽度比赛的?具体来说,您的正则表达式使用[\w++
。而且,[\w++
是多余的,可能有害。改用\w+
。str.replace(/\b(?)(或|和| NOT)\b)\w+/g,'contactTags:$&')
根据单词的正则表达式定义过滤单词-但您的可能会有所不同。你能添加更多关于可能匹配的细节吗?我已经将@anubhava的答案标记为已接受的答案,但之所以将其移动到@JamPow的答案,只是因为这是第一个答案,而且@sln上面的评论似乎表明,$1
比$&
更好。但谢谢你们两个!它似乎工作得很好@JakeLowen$1
比$&
差。这是regex引擎的额外开销。这个答案比anubhava的更糟糕,因为先行词没有固定在单词边界之后/(?!或|和|不)\b([\w]+)\b/g
将在单词内的每个位置运行(?!或|和|不)
。当放置在\b
之后时,它仅在单词边界之后执行。而且,首先检查单词边界比检查具有多个交替的组更容易。此外,[\w]
等于\w
-为什么在单独的字符类中使用单个原子?我完全同意@WiktorStribiżew,$1
在内存使用方面肯定比$&
差。它还通过避免不必要的捕获组来缩短正则表达式。@JakeLowen:在5.20之前的Perl版本中,$&
的使用导致Perl程序执行严重放缓。也许,sln的意思就是那种“问题”。但是,您没有使用Perl,而且无论在哪里支持它,$&
都可以使用。在Perl v.5.20+中也是如此。
const regex = /(?!OR|AND|NOT)\b([\w]+)\b/g;
let str = '(foo OR bar) AND baz NOT buz';
console.log(str.replace(regex, 'contactTags:$1'))