Split url string based on known start and end, with optional unknown in between segments

Viewed 90

Trying to split strings with a known starting segment and optional additional segments until a common endpoint.

eg.

https://example.com/folder/upload/v1/subfolder/asset.doc

https://example.com/folder/upload/temp_cache_folder_id/v1/subfolder/asset.doc

Basically need to remove anything between /upload/ and /v1/

Currently got as far as

string.split(/.*?(?=v1)/)

Not sure how to proceed looking back until /upload/ and return

[https://example.com/folder , v1/subfolder/asset.doc]

upload/temp_cache_folder_id is joined with certain env variables later so it isn't needed. That's why the split was done in the first place.

2 Answers

Use

/^(.*?)\/upload\/.*?(v1.*)/

See regex proof.

Explanation

--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    .*?                      any character except \n (0 or more times
                             (matching the least amount possible))
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  \/                       '/'
--------------------------------------------------------------------------------
  upload                   'upload'
--------------------------------------------------------------------------------
  \/                       '/'
--------------------------------------------------------------------------------
  .*?                      any character except \n (0 or more times
                           (matching the least amount possible))
--------------------------------------------------------------------------------
  (                        group and capture to \2:
--------------------------------------------------------------------------------
    v1                       'v1'
--------------------------------------------------------------------------------
    .*                       any character except \n (0 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
  )                        end of \2

JavaScript code:

const string = "https://example.com/folder/upload/v1/subfolder/asset.doc";
const [_, url, v1] = /^(.*?)\/upload\/.*?(v1.*)/.exec(string);
console.log("URL: " + url);
console.log("v1: " + v1);

Using split, you could match /upload/ followed by at least as possible chars until to can assert v1 to the right.

\/upload\/.*?\b(?=v1)

See a regex demo.

Explanation

  • \/upload\/ Match /upload/
  • .*? Match 0+ occurrences of any char except a newline, as least as possbile
  • \b(?=v1) A word boundary followed by a postive lookahead asserting v1 at the right.

[
  "https://example.com/folder/upload/v1/subfolder/asset.doc",
  "https://example.com/folder/upload/temp_cache_folder_id/v1/subfolder/asset.doc"
].forEach(s =>
  console.log(s.split(/\/upload\/.*?\b(?=v1)/))
);

Related