Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 字符串regex replace/prepend_Javascript_Regex_Algolia - Fatal编程技术网

Javascript 字符串regex replace/prepend

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参数中。(但实际上,这个问题更多的是关于正则表达式字符串的替换) 我可以生成一个正则表达式模

我需要将一个字符串从用户输入转换为搜索栏,这样我就可以在字符串中的任何单词前面加上“contactTags:”这不是一个特殊的搜索字符,比如(,),和,或者,不是搜索输入
(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'))