Every time I use JavaScript's regular expressions I inevitably have to relearn something. Today I am putting the finishing touches on a new web-based static analysis tool I'll blog about later, and I needed to do something simple: given a dehydra JS object that has been pushed through SpiderMonkey's uneval() function, I want to find and replace all instances of "Line: #," with the actual line of code I'm analyzing. Using the js shell, I did some quick tests:
js> x "blah blah blah line: 2, blah blah blah line: 3, blah blah line: 4, blah blah" js> /line: (\d+),/g.exec(x); ["line: 2,", "2"]
No matter what I tried, this always gave me the first match, and no more. Luckily, Gavin had the answer: exec() is meant to be called in a loop, and position info is cached. It's about the least obvious API choice I can imagine for doing this, but here you are:
js> var r=/line: (\d+),/g; while (m=r.exec("blah blah blah line: 2, blah blah blah line: 3, blah blah line: 4, blah blah")) print(m); line: 2,,2 line: 3,,3 line: 4,,4
Now you know, and I'll have something to search for on Google next time I have to relearn this!