You are correct that brackets and backslashes need to be escaped in a regular expression, but you can't create a regex by adding together regex literals like your /\[url href=/ + objectId + /\]/
attempt. To build a regex dynamically like that you have to use string concatenation and pass the result to new RegExp()
. So as a starting point for your text you'd need this:
new RegExp("\\[url href=" + objectId + "\\]" + objectId2 + "\\[/url\\]")
Note all of the double-backslashes - that's because backslashes need to be escaped in string literals, so "\\["
creates a string containing a single backslash and then a bracket, which is what you want in your regex.
But if you want to extract the matched href and content for use in creating an anchor then you need capturing parentheses:
new RegExp("\\[url href=(" + objectId + ")\\](" + objectId2 + ")\\[/url\\]")
But that's still not enough for your purposes because objectId
and objectId2
could (or will, given the first is a url) contain other characters that need to be escaped in a regex too, e.g., .+?()
, etc. So here's a function that can escape all of the necessary characters:
function escapeStringForRegex(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
We can't just call that function on the whole thing, because you need unescaped parentheses for your capturing sub matches, so just call it on the two variables:
var urlRegex = new RegExp("\\[url href=("
+ escapeStringForRegex(objectId)
+ ")\\]("
+ escapeStringForRegex(objectId2)
+ ")\\[/url\\]");
Kind of messy, but seems to do the job as you can see here:
function escapeStringForRegex(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
function createAnchors(str, objectId, objectId2) {
var urlRegex = new RegExp("\\[url href=(" + escapeStringForRegex(objectId) + ")\\](" + escapeStringForRegex(objectId2) + ")\\[/url\\]", "g");
return str.replace(urlRegex, "<a href='$1'>$2</a>");
}
document.querySelector("button").addEventListener("click", function() {
var str = document.getElementById("input").value;
var objectId = document.getElementById("objectId").value;
var objectId2 = document.getElementById("objectId2").value;
document.getElementById("output").value =
createAnchors(str, objectId, objectId2);
});
textarea { width : 100%; height: 80px; }
Input:<br><textarea id="input">This is just some text that you can edit to try things out. [url href=http://test.com.au?param=1]Test URL[/url]. Thanks.</textarea>
ObjectId:<input id="objectId" value="http://test.com.au?param=1"><br>
ObjectId2:<input id="objectId2" value="Test URL"><br>
<button>Test</button>
<textarea id="output"></textarea>
Note that the above searches only for [url]
s in your string that have the particular href and content specified in the objectId
and objectId2
variables. If you just want to change all [url]
s into anchors regardless of what href and text they contain then use this:
.replace(/\[url href=([^\]]+)\]([^\]]+)\[\/url\]/g, "<a href='$1'>$2</a>")
Demo:
function escapeStringForRegex(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
function createAnchors(str) {
return str.replace(/\[url href=([^\]]+)\]([^\]]+)\[\/url\]/g, "<a href='$1'>$2</a>");
}
document.querySelector("button").addEventListener("click", function() {
var str = document.getElementById("input").value;
document.getElementById("output").value = createAnchors(str);
});
textarea { width : 100%; height: 80px; }
Input:<br><textarea id="input">Testing. [url href=http://test.com.au?param=1]Test URL[/url]. Thanks. Another URL: [url href=https://something.com/test?param=1&param2=123]Test URL 2[/url]</textarea>
<button>Test</button>
<textarea id="output"></textarea>