I have a regex expression which removes any backslashes from a string if not followed by one of these characters: \\ / or }.
It should turn this string:
<
You need to watch out for an escaped backslash, followed by a single backslash. Or better: an uneven number of successive backslashes. In that case, you need to keep the even number of backslashes intact, and only replace the last one (if not followed by a /
or {
).
You can do that with the following regex:
(?<!\\)(?:((\\\\)*)\\)(?![\\/{])
and replace it with:
$1
where the first match group is the first even number of backslashes that were matched.
A short explanation:
(?<!\\) # looking behind, there can't be a '\'
(?:((\\\\)*)\\) # match an uneven number of backslashes and store the even number in group 1
(?![\\/{]) # looking ahead, there can't be a '\', '/' or '{'
In plain ENglish that would read:
match an uneven number of back-slashes,
(?:((\\\\)*)\\)
, not followed by\\
or{
or/
,(?![\\/{])
, and not preceded by a backslash(?<!\\)
.
A demo in Java (remember that the backslashes are double escaped!):
String s = "baz\\\\\\foo\\bar\\\\batz\\/hi";
System.out.println(s);
System.out.println(s.replaceAll("(?<!\\\\)(?:((\\\\\\\\)*)\\\\)(?![\\\\/{])", "$1"));
which will print:
baz\\\foo\bar\\batz\/hi
baz\\foobar\\batz\/hi
And a solution that does not need look-behinds would look like:
([^\\])((\\\\)*)\\(?![\\/{])
and is replaced by:
$1$2
where $1
is the non-backslash char at the start, and $2
is the even (or zero) number of backslashes following that non-backslash char.
The required regex is as simple as \\.
You need to know however, that the second argument to replace()
can be a function like so:
result = string.replace(/\\./g, function (ab) { // ab is the matched portion of the input string
var b = ab.charAt(1);
switch (b) { // if char after backslash
case '\\': case '}': case '/': // ..is one of these
return ab; // keep original string
default: // else
return b; // replace by second char
}
});
You need a lookahead, like you have, and also a lookbehind, to ensure that you dont delete the second slash (which clearly doesnt have a special character after it. Try this:
(?<![\\])[\\](?![\\\/\}])
as your regex