Javascript Regular Expressions Lookbehind Failing


I am hoping that this will have a pretty quick and simple answer. I am using <a href="http://www.regular-expressions.info/javascriptexample.html" rel="nofollow">regular-expressions.info</a> to help me get the right regular expression to turn URL-encoded, ISO-8859-1 pound sign ("%A3"), into a URL-encoded UTF-8 pound sign ("%C2%A3").

In other words I just want to swap %A3 with %C2%A3, when the %A3 is not already prefixed with %C2.

So I would have thought the following would work:

Regular Expression: (?!(\%C2))\%A3 Replace With: %C2%A3

But it doesn't and I can't figure out why!

I assume my syntax is just slightly wrong, but I can't figure it out! Any ideas?

FYI - I know that the following will work (and have used this as a workaround in the meantime), but really want to understand why the former doesn't work.

Regular Expression: ([^\%C2])\%A3 Replace With: $1%C2%A3



Why not just replace ((%C2)?%A3) with %C2%A3, making the prefix an optional part of the match? It means that you're "replacing" text with itself even when it's already right, but I don't foresee a performance issue.


Unfortunately, the (?!) syntax is negative lookahead. To the best of my knowledge, JavaScript does not support negative lookbehind.

What you could do is go forward with the replacement anyway, and end up with %C2%C2%A3 strings, but these could easily be converted in a second pass to the desired %C2%A3.


You could replace





I would suggest you use <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/String/replace" rel="nofollow">the functional form of Javascript String.replace</a> (see the section "Specifying a function as a parameter"). This lets you put arbitrary logic, including state if necessary, into a regexp-matching session. For your case, I'd use a simpler regexp that matches a superset of what you want, then in the function call you can test whether it meets your exact criteria, and if it doesn't then just return the matched string as is.

The only problem with this approach is that if you have overlapping potential matches, you have the possibility of missing the second match, since there's no way to return a value to tell the replace() method that it isn't really a match after all.


  • how to show gif image while uploading using jquery form plugin in asp.net mvc
  • alpha and beta estimates for beta binomial and beta distributions
  • Web method is not called by jquery from javascript function
  • Does .zip compression internally maintain a checksum?
  • UITableview Cell exception - 'Must translate autoresizing mask into constraints to have _setHos
  • LINQ groupby statement with key
  • PHP relative path: can I configure it?
  • re.sub replace spaces with comma
  • Database abstraction with Julia
  • Control key plus mouse wheel
  • How to call R functions from Fortran?
  • Mouse up vs. touch up in Unity
  • How to Mantain Session with AngularJS Website from Native App?
  • Netlify fails to deploy site after public is added to .gitignore
  • Heroku Rails 4— FileNotFound jquery.ui.all
  • Add lots of data to SQLite Database in C#
  • How to get internal link from latest revision of a wikipedia page?
  • Python mock a base class's attribute
  • Why $.each() is slower than for loop in jquery?
  • Python 3.7 Docker images
  • Why does IntStream.range(0, 100000).parallel.foreach take longer then normal for loop
  • Adding a delete button in PHP on each row of a MySQL table
  • How to install or uninstall SonarQube plug-ins with HTTP?
  • Storyboard iOS MBProgressHUD
  • How to add CKEditor RTE to typo3 Backend Module with the API?
  • Javapackager tool from command-line on OSX?
  • How do I detect if an email client is configured on an Android device?
  • Trigger powershell based on event log
  • Python tk scrollbar becomes inactive once text is outside the screen
  • ROR + MVC Disable Browser Cache
  • create circular Auto Horizontal Scroll View?
  • How to modify the way a ForeignKey field is rendered in a Django admin page to avoid browser crash?
  • C++11: Why rvalue reference parameter implicitly converted to lvalue
  • Adding horizontal slider to QTableWidget
  • Pick Out Specific Number from Array? [duplicate]
  • Julia 1.0 UndefVarError - Scope of Variable
  • How to merge objects within array based on attribute
  • how to get the location(lat/lng) on google maps v3 from the location(x,y)
  • Change cell value based on cell color in google spreadsheet
  • Update cell query for Excel ADO from Delphi