Replace all character matches that are not escaped with backslash

时间:2015-07-31 20:53:03

标签: javascript regex

I am using regex to replace ( in other regexes (or regexs?) with (?: to turn them into non-matching groups. My expression assumes that no (?X structures are used and looks like this:

(
  [^\\]     - Not backslash character
  |^        - Or string beginning
)
(?:
  [\(]      - a bracket
)

Unfortunatelly this doesn't work in case that there are two matches next to each other, like in this case: how((\s+can|\s+do)(\s+i)?)?

image description

With lookbehinds, the solution is easy:

/(?<=[^\\]|^)[\(]/g

But javascript doesn't support lookbehinds, so what can I do? My searches didn't bring any easy universal lookbehind alternative.

3 个答案:

答案 0 :(得分:2)

通过逆转使用lookbehind:

function revStr(str) {
    return str.split('').reverse().join('');
}

var rx = /[(](?=[^\\]|$)/g;
var subst = ":?(";

var data = "how((\\s+can|\\s+do)(\\s+i)?)?";
var res = revStr(revStr(data).replace(rx, subst)); 
document.getElementById("res").value = res;
<input id="res" />

请注意,正则表达式模式也是相反的,因此我们可以使用预测而不是后视,并且替换字符串也是相反的。使用更长的正则表达式会变得太棘手,但在这种情况下,它仍然不是那么难以理解。

答案 1 :(得分:2)

一种选择是使用令牌进行双程替换(我喜欢unicode,因为它不太可能出现在其他地方):

&#13;
&#13;
var s = 'how((\\s+can|\\s+do)(\\s+i)?)?';
var token = "\u1234";
// Look for the character preceding the ( you want
// to replace. We'll add the token after it.
var patt1 = /([^\\])(?=\()/g;
// The second pattern looks for the token and the (.
// We'll replace both with the desired string.
var patt2 = new RegExp(token + '\\(', 'g');

s = s.replace(patt1, "$1" + token).replace(patt2, "(?:");

console.log(s);
&#13;
&#13;
&#13;

https://jsfiddle.net/48e75wqz/1/

答案 2 :(得分:0)

(修改)

字符串示例:

how((\s+can|\s+do)(\s+i)?)?

一线解决方案:

&#13;
&#13;
o='how((\\s+can|\\s+do)(\\s+i)?)?';
alert(o.replace(/\\\(/g,9e9).replace(/\(/g,'(?:').replace(/90{9}/g,'\\('))
&#13;
&#13;
&#13;

结果:

how(?:(?:\s+can|\s+do)(?:\s+i)?)?

当然它适用于字符串如何((\ s + \(can\) | \ s + do)(\ s + i)?)?