Regex to replace single backslashes, excluding those followed by certain chars

天大地大妈咪最大 提交于 2019-12-01 04:58:22
Bart Kiers

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

EDIT

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!