Matt Wolin
Matt Wolin

Reputation: 701

Replace Everything After the 3rd Occurrence of a Character if Present

Here is what I am trying to do:

Given a string, if the string starts with "/plan", I want to remove everything after the third occurrence of the '/' character — assuming there is a third occurrence, which there may not be. If it begins with "/plan", but has fewer than 3 '/' characters, the regex should return the string as is.

Additionally, if the string doesn't begin with "/plan", the string can be returned as is. Here are some sample inputs and outputs:

"" returns ""
"/foo" return "/foo"
"/plan/123" returns "/plan/123"
"/plan/123/4567" returns "/plan/123"
"/plan/123/4567/89010" returns "/plan/123

Ideally, I would like to do this entirely through a regex, but given some of the requirements, I realize that it might not be easily accomplished.

Upvotes: 1

Views: 2742

Answers (3)

Niccolò Campolungo
Niccolò Campolungo

Reputation: 12042

Without a Regex you can do it using simple string splits:

function planReplace(str) {
    var split = str.split('/');
    if (split.length < 2) return str;
    if (split[1] === 'plan') return "/" + split[1] + "/" + split[2];
    //this line can even be shorter, but it would use a bit more memory:
    //if (split[1] === 'plan') return split.splice(0, 3).join('/');
    return str;
}

Upvotes: 2

T.J. Crowder
T.J. Crowder

Reputation: 1074148

Here's a way using a regular expression and replace:

var str = /* ... */;
str = str.replace(/^(\/plan\/[^\/]+)\/.*$/, '$1');

That does this:

  1. Capture:
    • Match /plan at start of string
    • ...followed by /
    • ...followed by one or more non-/
  2. Match a following / followed by anything to end of string
  3. Replace the full match with the first capture group

(And if there's no match, there's no replacement.)

Testing: Live Copy | Source

var tests = [
    {test: "", expect: ""},
    {test: "/foo", expect: "/foo"},
    {test: "/plan/123", expect: "/plan/123"},
    {test: "/plan/123/4567", expect: "/plan/123"},
    {test: "/plan/123/4567/89010", expect: "/plan/123"}
  ];

var index, test, result;
for (index = 0; index < tests.length; ++index) {
  test = tests[index];
  result = test.test.replace(/^(\/plan\/[^\/]+)\/.*$/, '$1');
  if (result === test.expect) {
    display("OK: " + test.test + " => " + result);
  }
  else {
    display("FAIL: " + test.test + " => " + result);
  }
}

Results:

OK: =>
OK: /foo => /foo
OK: /plan/123 => /plan/123
OK: /plan/123/4567 => /plan/123
OK: /plan/123/4567/89010 => /plan/123

Upvotes: 4

Paul
Paul

Reputation: 141839

You can use the regex (^/plan/[^/]*).*$ like so:

var str = "/plan/123/4567/89010";
str.replace(/(^\/plan\/[^\/]*).*$/, '$1');

Upvotes: 0

Related Questions