Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace all character matches that are not escaped with backslash

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.

like image 268
Tomáš Zato - Reinstate Monica Avatar asked Jul 31 '15 20:07

Tomáš Zato - Reinstate Monica


People also ask

Do you need to escape ampersand in regex?

Thanks. @RandomCoder_01 actually, no escapes are needed. & is not a special regex character, so no need to escape it.

How to escape in regex pattern?

The \ is known as the escape code, which restore the original literal meaning of the following character. Similarly, * , + , ? (occurrence indicators), ^ , $ (position anchors) have special meaning in regex. You need to use an escape code to match with these characters.

How to escape in regex in c#?

\ Is also an escape character for string literals in c# so the first \ is escaping the second \ being passed to the method and the second one is escaping the . in the regex. Use: if (Regex.

How do you replace a single slash in Java?

Replacing a Single Backslash( \ ) With a Double Backslash( \\ ) Using the replaceAll() Method. This is another solution that you can use to replace the backslashes. Here, we used the replaceAll() method that works fine and returns a new String object.


2 Answers

Use lookbehind through reversal:

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" />

Note that the regex pattern is also reversed so that we could use a look-ahead instead of a look-behind, and the substitution string is reversed, too. It becomes too tricky with longer regexps, but in this case, it is still not that unreadable.

like image 114
Wiktor Stribiżew Avatar answered Oct 26 '22 01:10

Wiktor Stribiżew


One option is to do a two-pass replacement, with a token (I like unicode for this, as it's unlikely to appear elsewhere):

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);

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

like image 41
nrabinowitz Avatar answered Oct 26 '22 02:10

nrabinowitz