如何在正则表达式中正确转义字符

问题描述:

我想在字符串内进行字符串搜索。简单地说MySTR.search(Needle)如何在正则表达式中正确转义字符

当这个needle字符串包含像*,+等特殊的正则表达式字符时,就会出现问题。它失败,错误invalid quantifier

我浏览了网页,发现字符串可以用\Q some string \E转义。

但是,这并不总是产生所需的行为。例如:

var sNeedle = '*Stars!*'; 
var sMySTR = 'The contents of this string have no importance'; 
sMySTR.search('\Q' + sNeedle + '\E'); 

结果是-1。好。

var sNeedle = '**Stars!**'; 
var sMySTR = 'The contents of this string have no importance'; 
sMySTR.search('\Q' + sNeedle + '\E'); 

结果是“无效量词”。发生这种情况是因为两个或多个特殊字符彼此“触摸”,因为:

var sNeedle = '*Dont touch me*Stars!*Dont touch me*'; 
var sMySTR = 'The contents of this string have no importance'; 
sMySTR.search('\Q' + sNeedle + '\E'); 

将工作正常。

我知道我可以制作一个函数escapeAllBadChars(sInStr),并且在每个可能的特殊正则表达式字符前加上双斜杠,但是我想知道是否有更简单的方法来做到这一点?

+3

\ Q ... \ e可在Perl,不知道尽管在其他地方。 – 2011-04-14 13:54:32

+1

我认为你的第三个例子中的星星没有做你的想法。它们不被解释为文字*字符,而是作为前面的字符的量词。 – 2011-04-14 13:59:39

+0

@Matthew,在Java中它的工作方式与Perl相同(不确定其他语言)。 – 2011-04-14 14:01:03

\Q...\E在JavaScript中不工作(至少,他们不会逃避任何东西......),你可以看到:

var s = "*"; 
print(s.search(/\Q*\E/)); 
print(s.search(/\*/)); 

生产:

-1 
0 

,你可以看到在Ideone

以下字符需要进行转义:

  • (
  • )
  • [
  • {
  • *
  • +
  • .
  • $
  • ^
  • \
  • |
  • ?

所以,像这样的事:

function quote(regex) { 
    return regex.replace(/([()[{*+.$^\\|?])/g, '\\$1'); 
} 

不,]}不需要转义:它们没有特别的含义,只有它们的开放柜台部分。

请注意,当使用文字正则表达式/.../时,还需要转义/ char。但是,/不是正则表达式元字符:在RegExp对象中使用它时,不需要转义。

+1

粉碎答案! – 2011-07-14 10:45:50

+0

字符/需要被转义以及 – lopata 2015-06-02 07:51:02

+0

@TheoZ,我不会调用'/'de regex meta char。只有在使用文字正则表达式时才需要转义。当用'RegExp'对象创建正则表达式时,它不需要转义。但是因为我用'/.../'给出了一个例子,所以最好提一下它。 – 2015-06-02 08:03:11

我执行了一个快速谷歌搜索,看看那里有什么,它似乎有几个选项用于转义正则表达式字符。据one page,您可以定义&运行的函数像下面逃避问题的字符:

RegExp.escape = function(text) { 
    return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 
} 

或者,你可以尝试使用一个单独的库如XRegExp,已经处理你想重新细微差别解决。

我只是把脚放在Javascript中,但是有没有理由需要使用正则表达式引擎?如何

var sNeedle = '*Stars!*'; 
var sMySTR = 'The contents of this string have no importance'; 
if (sMySTR.indexOf(sNeedle) > -1) { 
    //found it 
} 
+0

我还没有真正想过这个。它只是卡在我的脑海,我应该使用.search().match().replace()与字符串。事实上,我想要做的就是使用sNeedle作为简单的文本字符串,所以我认为indexOf肯定是个好主意。 – user1651105 2011-04-14 14:13:26

https://stackoverflow.com/a/6969486/151312

复制这是正确的按MDN(参见后解释以上):

function escapeRegExp(str) { 
    return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); 
}