0

I have the following string,

Some text ![test1](assets/image1.png) \n some text ![test2](https://example.com/assets/image2.png) some other text \n ![test3](assets/image3.png)

I want to replace all the relative image paths i.e. assets/image1.png to https://example.com/assets/image1.png and same for assets/image3.png. But we need to ignore https://example.com/assets/image2.png as it is already absolute path.

So far I have been able to do the following,

const getImagesWithAbsolutePath = (text, absolutePathPrefix) => {
    if (!text) return ''
    const regex = /(\!\[.*\]\()(.*)(\))/g
    return text.replace(regex, '$1' + absolutePathPrefix + '/$2?raw=true$3')
}

myText = "Some text ![test1](assets/image1.png) \n some text ![test2](https://example.com/assets/image2.png) some other text \n ![test3](assets/image3.png)";

myDomain = "https://example.com";

console.log(getImagesWithAbsolutePath(myText, myDomain));

As you can see the output is,

 Some text ![test1](https://example.com/assets/image1.png?raw=true) 
 some text ![test2](https://example.com/https://example.com/assets/image2.png?raw=true) some other text 
 ![test3](https://example.com/assets/image3.png?raw=true)

But I need the result to be,

Some text ![test1](https://example.com/assets/image1.png?raw=true) 
some text ![test2](https://example.com/assets/image2.png?raw=true) some other text 
![test3](https://example.com/assets/image3.png?raw=true)
sabbir.alam
  • 4,512
  • 2
  • 12
  • 26

1 Answers1

1

You need to

  • Use lazy dot / negated character classes to make sure you do not match across your (/) and [/] delimiters
  • Match the myDomain host part optionally, so that it could be removed when you add it back with the replacement:

const myDomain = "https://example.com";
const getImagesWithAbsolutePath = (text, absolutePathPrefix) => {
    if (!text) return ''
    const regex =  new RegExp("(!\\[.*?]\\()(?:" + myDomain.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "/*)?(.*?)(\\))", "g")
    return text.replace(regex, '$1' + absolutePathPrefix + '/$2?raw=true$3')
}

let myText = "Some text ![test1](assets/image1.png) \n some text ![test2](https://example.com/assets/image2.png) some other text \n ![test3](assets/image3.png)";

console.log(getImagesWithAbsolutePath(myText, myDomain));

See the regex demo.

Details:

  • (!\[.*?]\() - Group 1: !, [, any zero or more chars other than line break chars as few as possible, ](
  • (?:https:\/\/example\.com\/*)? - an optional occurrence of https://example.com string and then zero or more / chars
  • (.*?) - Group 2: any zero or more chars other than line break chars as few as possible
  • (\)) - Group 3: ) char.

NOTE: if you happen to have $ + digit in the absolutePathPrefix (myDomain), you will need to replace with '$1' + absolutePathPrefix.replace(/\$/g, '$$$$') + '/$2?raw=true$3'.

Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397