Skip to content

Instantly share code, notes, and snippets.

@benjie
Created June 28, 2012 19:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benjie/3013247 to your computer and use it in GitHub Desktop.
Save benjie/3013247 to your computer and use it in GitHub Desktop.
How NOT to write a RegExp

The below code (regexp-freeze.coffee) makes V8 lock up (both NodeJS and Chrome). It's my fault for nesting repeats (+), but it would be nice if V8 (or it's RegExp library) detected this lock-up in some way - I don't think there's many situations in which it's okay for a RegExp to take more than a second on a 134byte string on a modern desktop computer...

How not to write it:

/`((?:[^\\`\n]+|(?:\\[^\n]))+)`/g

How to write it:

/`((?:[^\\`\n]|\\[^\n])+)`/g

NOTE: Only one repeat operator - no repeat nesting.

Lesson: Don't Nest Repeat Operators

# Run this script through coffee as `coffee regexp-freeze.coffee freeze1`
#
# To run it in the browser, replace `process.argv[2]` with your option of choice, and remove `process.exit 1`
str = """```for (var i = 0; i < Math.ceil(rawIds.length / 100); i++)
for (var j = 0; j < 100; j++) {
userStore[i] = rawIds[j].shift();
}
}```"""
regexp = switch process.argv[2]
when "freeze1" then /`((?:[^\\`\n]+|(?:\\[^\n]))+)`/g
when "freeze2" then /`((?:[^\\`\n]+|\\[^\n])+)`/g
when "freeze3" then /`(([^\\`\n]+(\\[^\n])*)+)`/g
when "freeze4" then /\`([^\\\`\n]+(\\[^\n])?)+\`/g
when "ok1" then /`((?:[^\\`\n]|\\[^\n])+)`/g
else
console.log "Please specify freeze[1-4] or ok1"
process.exit 1
console.log "Running regexp..."
matches = regexp.exec(str)
console.dir matches
console.log "Done"
@dingram
Copy link

dingram commented Jun 28, 2012

Sorry to nit-pick, but + is greedy - +? is non-greedy. Good spot though.

@benjie
Copy link
Author

benjie commented Jun 28, 2012

Whoops, I meant to remove that when I realised it was nothing to do with greediness, just nesting. Thanks for the heads up :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment