我正在用javascript编写一个替换空格的正则表达式,除非:
- 一些特定的语法在空格前面
- 它被单引号和双引号包围(引号内的转义引号除外)
现在,我有很大一部分工作。它匹配在空格前面没有特定语法的所有模式,但是,我坚持使用引号部分。
return str.replace(/(function|new|return|var)?\s/g, function($0, $1) {
return $1 ? $0 : '';
});
我已经做了很多测试,但我就是想不通。提前致谢。
我正在用javascript编写一个替换空格的正则表达式,除非:
现在,我有很大一部分工作。它匹配在空格前面没有特定语法的所有模式,但是,我坚持使用引号部分。
return str.replace(/(function|new|return|var)?\s/g, function($0, $1) {
return $1 ? $0 : '';
});
我已经做了很多测试,但我就是想不通。提前致谢。
您可以使用:
var str = "foo \"b a \\\" r\" new y 'l o l' foo lol; var x = new 'fo \\' o' ";
var result = str.replace(/(function|new|return|var)?\s+(?=(?:[^\\"']|\\.)*(?:(?:"(?:[^\\"]|\\.)*"|'(?:[^\\']|\\.)*'))*(?:[^\\"']|\\.)*$)/gm,
function($0, $1) { return $1 ? $0 : ''; });
Perl/x
形式的前瞻部分:
s/
\s+
(?=
(?:[^\\"']|\\.)*
(?:
(?:
"(?:[^\\"]|\\.)*"
|
'(?:[^\\']|\\.)*'
)
)*
(?:[^\\"']|\\.)*$
)
//xmg;
注意:正如我之前所说,这不是解析 JS 的好方法,并且会破坏注释、正则表达式引用以及谁知道还有什么。
注意2:忘记补充这仅适用于“有效”报价,所有报价必须关闭。
我的建议:
模仿javascript中的lookbehind(尽管这个hack可能并不完美)。
使用递归下降解析器(也许是 antlr)?
或者手动编写代码为您完成。下面是我在想什么的第一个草稿版本(还有一些伪代码):
function go(str) {
var quoteStart, quoteEnd, quotedRanges, from, retval;
quotedRanges = []; //quotedRanges holds the indexes inclusively within which nothing should be changed because it's quoted.
quoteStart = str.indexOf('"');
if( quoteStart > -1 ) {
from = quoteStart;
while (from !== false) {
quoteEnd = str.indexOf('"', from);
if (quoteEnd == -1) { //There is an unmatched quote. We pretend that it is closed off at the end of the string.
quoteEnd = str.len;
from = false;
} else if(str.charAt(quoteEnd - 1) == "\\") {
from = quoteEnd;
} else { //we found the ending quote index.
from = false;
}
}
quotedRanges.push([quoteStart, quoteEnd]);
}
retval = str.replace(/(function|new|return|var)?\s/g, function($0, $statement) {
if($0 within on of quotedRanges)
return $0;
return $statement ? $0 : '';
});
return retval;
}
assert(1, go("") == "");
assert(2, go("function ") == "function ");
assert(3, go(" ") == "");
assert(4, go('" "') == '" "');
assert(5, go('" ') == '" ');
assert(6, go('"x x"') == '"x x"');
assert(6, go('"new x"') == '"new x"');
assert(7, go(' "x x"') == '"x x"');
assert(8, go("' '") == "' '");
assert(9, go("' \\' '") == "' \\' '");
function assert(num, statement) {
if(!statement) {
document.write('test #' + num + ' failed! <br/>');
}
}