3

I am trying to find a regular expression that will match a string when it's NOT preceded by another specific string (in my case, when it is NOT preceded by "http://"). This is in JavaScript, and I'm running on Chrome (not that it should matter).

The sample code is:

var str = 'http://www.stackoverflow.com www.stackoverflow.com';
alert(str.replace(new RegExp('SOMETHING','g'),'rocks'));

And I want to replace SOMETHING with a regular expression that means "match www.stackoverflow.com unless it's preceded by http://". The alert should then say "http://www.stackoverflow.com rocks", naturally.

Can anyone help? It feels like I tried everything found in previous answers, but nothing works. Thanks!

Assaf Hershko
  • 1,693
  • 3
  • 16
  • 19

2 Answers2

4

As JavaScript regex engines don't support 'lookbehind' assertions, it's not possible to do with plain regex. Still, there's a workaround, involving replace callback function:

var str = "As http://JavaScript regex engines don't support `lookbehind`, it's not possible to do with plain regex. Still, there's a workaround";

var adjusted = str.replace(/\S+/g, function(match) {
  return match.slice(0, 7) === 'http://'
    ? match
    : 'rocks'
});
console.log(adjusted);

You can actually create a generator for these functions:

var replaceIfNotPrecededBy = function(notPrecededBy, replacement) {
   return function(match) {
     return match.slice(0, notPrecededBy.length) === notPrecededBy
       ? match
       : replacement;
   }
};

... then use it in that replace instead:

var adjusted = str.replace(/\S+/g, replaceIfNotPrecededBy('http://', 'rocks'));

JS Fiddle.

raina77ow
  • 91,589
  • 12
  • 180
  • 210
0

This also works:

var variable = 'http://www.example.com www.example.com';
alert(variable.replace(new RegExp('([^(http:\/\/)|(https:\/\/)])(www.example.com)','g'),'$1rocks'));

The alert says "http://www.example.com rocks".

Assaf Hershko
  • 1,693
  • 3
  • 16
  • 19
  • 1
    It works, but not in the way you think it does. Basically, as character class regex operator is used, you're just replacing a sequence of any symbol that's not in 'htps:/()|' range, followed by `www.example.com`. It'll give you a lot of false positives, first, and it's plain redundant, second. – raina77ow Sep 19 '13 at 18:59