Try using a negative lookahead.
(?!\.jpg)
What you have now, [^\.jpg]
is saying "any character BUT a period or the letters j, p, or g".
EDIT Here's an answer using negative look ahead and file extensions.
Update
Knowing this is a "url finder" now, here's a better solution:
// parseUri 1.2.2
// (c) Steven Levithan <stevenlevithan.com>
// MIT License
// --- http://blog.stevenlevithan.com/archives/parseuri
function parseUri (str) {
var o = parseUri.options,
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
uri = {},
i = 14;
while (i--) uri[o.key[i]] = m[i] || "";
uri[o.q.name] = {};
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
if ($1) uri[o.q.name][$1] = $2;
});
return uri;
};
parseUri.options = {
strictMode: false,
key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
q: {
name: "queryKey",
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
},
parser: {
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
}
};//end parseUri
function convertUrls(element){
var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig
element.innerHTML = element.innerHTML.replace(urlRegex,function(url){
if (parseUri(url).file.match(/\.(jpg|png|gif|bmp)$/i))
return '<img src="'+url+'" alt="'+url+'" />';
return '<a href="'+url+'">'+url+'</a>';
});
}
I used a parseUri method and a slightly different RegEx for detecting the links. Between the two, you can go through and replace the links within an element with either a link or the image equivalent.
Note that my version checks most images types using /\.(jpg|png|gif|bmp)$/i
, however this can be altered to explicitly capture jpg using /\.jpg$/i
. A demo can be found here.
The usage should be pretty straight forward, pass the function an HTML element you want parsed. You can capture it using any number of javascript methods (getElementByID, getElementsByTagName, ...). Hand it off to this function, and it will take care of the rest.
You can also alter it and add it tot he string protoype so it can be called natively. This version could be performed like so:
String.prototype.convertUrls = function(){
var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig
return this.replace(urlRegex,function(url){
if (parseUri(url).file.match(/\.(jpg|png|gif|bmp)$/i))
return '<img src="'+url+'" alt="'+url+'" />';
return '<a href="'+url+'">'+url+'</a>';
});
}
function convertUrls(element){
element.innerHTML = element.innerHTML.convertUrls();
}
(Note the logic has moved to the prototype function and the element function just calls the new string extension)
This working revision can be found here