Reputation: 2536
I have this RegExp expression I found couple weeks ago
/([\r\n])|(?:\[([a-z\*]{1,16})(?:=([^\x00-\x1F"'\(\)<>\[\]]{1,256}))?\])|(?:\[\/([a-z]{1,16})\])/ig
And it's working to find the BBCode tags such as [url]
and [code]
.
However if I try [url="http://www.google.com"]
it won't match. I'm not very good at RegExp and I can't figure out how to still be valid but the ="http://www.google.com"
be optional.
This also fails for [color="red"]
but figure it is the same issue the url tag is having.
Upvotes: 3
Views: 256
Reputation: 17899
I think you would benefit from explicitly enumerating all the tags you want to match, since it should allow matching the closing tag more specifically.
Here's a sample code:
var tags = [ 'url', 'code', 'b' ]; // add more tags
var regParts = tags.map(function (tag) {
return '(\\[' + tag + '(?:="[^"]*")?\\](?=.*?\\[\\/' + tag + '\\]))';
});
var re = new RegExp(regParts.join('|'), 'g');
You might notice that the regular expression is composed from a set of smaller ones, each representing a single tag with a possible attribute ((?:="[^"]*")?
, see explanation below) of variable length, like [url="google.com"]
, and separated with the alternation operator |
.
(="[^"]*")?
means an =
symbol, then a double quote, followed by any symbol other than double quote ([^"]
) in any quantity, i.e. 0 or more, (*
), followed by a closing quote. The final ?
means that the whole group may not be present at all.
Upvotes: 1
Reputation: 18979
This part: [^\x00-\x1F"'\(\)<>\[\]]
says that after the =
there must not be a ". That means your regexp matches [url=http://stackoverflow.com]
. If you want to have quotes you can simply put them around your capturing group:
/([\r\n])|(?:\[([a-z\*]{1,16})(?:="([^\x00-\x1F"'\(\)<>\[\]]{1,256})")?\])|(?:\[\/([a-z]{1,16})\])/gi
Upvotes: 1