17

I wanted to build a JS function concatting a list of arguments to a valid path (since I could not be sure whether a part of the path is given with or without slashes)

This is the function:

concatPath = function() {
    var path = "";
    for(var i = 0; i < arguments.length; i++)   {
        path += arguments[i].replace("(\\|/)$|^(\\|/)", "") + "/";
    }
    return path;
}

The used RegEx matched all beginning and ending slashes and backslashes on http://regexpal.com But the function does not work properly (RegEx does not match). Furthermore, Chrome states

SyntaxError: Invalid regular expression: /()$|^()/: Unterminated group

when I just use the RegEx

 (\\)$|^(\\)

However, using the RegEx

 (\\)$|^(\\)

works fine.

Is it too late or did I missed something special?

Thanks in advance!

Leo

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Leo Selig
  • 1,062
  • 1
  • 16
  • 30

2 Answers2

22

You should use a regular expression literal (/.../) instead of a string literal ('...' or "...") in the call to replace. Strings have their own interpretation of backslashes that kicks in before the regular expression constructor gets a crack at it, so you need an extra level of quoting.

Match one backslash, regular expression literal: /\\/

Match one backslash, regular expression in a string: '\\\\'

But in a regex literal, you also have to put backslashes in front of the forward slashes, since forward slashes are the delimiter for the whole thing:

path += arguments[i].replace(/(\\|\/)$|^(\\|\/)/, "") + "/";

Or, if you're married to the use of strings for some reason, this should also work:

path += arguments[i].replace("(\\\\|/)$|^(\\\\|/)", "") + "/";

As a side note, when your alternatives are single characters, (x|y) is overkillish; you can just use a character class ([xy]). In which case you get this:

path += arguments[i].replace(/[\\\/]$|^[\\\/]/, "") + "/";

path += arguments[i].replace("[\\\\/]$|^[\\\\/]", "") + "/";
Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • thanks a lot, that did it can u also tell me why i would have to use '\\\\'? I thought "\\" would be enough since I need one backslash prevent it from escaping the " – Leo Selig May 28 '12 at 13:09
  • watch out for needing to backslash things in StackOverflow comments, too... :) When you use the string form, you're going through two parsers - the Javascript parser, which is building the string out of the source code, and the Regexp parser, which is building a regular expression out of the string. The regexp has to have two backslashes, but in order to get a single backslash in a string from a literal, you have to double it. Together, that means four backslashes. Try this: `alert("--> \\\\ <--")` - what you see is what Regexp.new sees when you pass a string to `replace`. – Mark Reed May 29 '12 at 15:14
  • you're welcome! you should accept an answer (mine or agent-j's) so that folks will be more likely to answer your questions in the future. – Mark Reed Jun 03 '12 at 14:37
  • 1
    Using a string lets you drop variables in. #usecase – Stephen Last Sep 08 '16 at 08:28
7

Try this... it's a little easier to follow with the [character classes]. to match a single \ with a javascript string you need \\\\, which may be what's going on.

new Regexp('^[\\\\/]|[\\\\/]$')

You can also try the /^[\\\/]|[\\\/]$/g notation.

s = 'c:\\folder\\'
console.log(s.replace(/^[\\\/]|[\\\/]$/g, ''))
agent-j
  • 27,335
  • 5
  • 52
  • 79