Skip to content

Instantly share code, notes, and snippets.

@kch
Created November 29, 2009 22:33
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 kch/245098 to your computer and use it in GitHub Desktop.
Save kch/245098 to your computer and use it in GitHub Desktop.
format numbers with separators using a single regex substitution operation
require 'yaml'
RX = /(\d)(?=\d{3}+(?!\d))/
# Long version
RX_LONG = /
(\d) # One digit
(?= # That is followed by
\d{3}+ # One or more triples of digits
(?!\d) # That are not followed by a digit
)
/x
ns = %w[
1
12
123
1234
12345
123456
1234567
12345678
123456789
]
y ns.map { |s| s.gsub(RX, '\\1.') }
y "random 324123415 13445foo345345whatever4554".gsub(RX, '\\1.')
# I like programming that is declarative, and regular expressions fit the bill.
# You define a pattern, and the computer figures out what to do with it.
# There's no algorithmic hand-holding telling the machine how to go about it.
#
# The substitutions performed above place thousands separators in number
# strings. The regex used simply defines the places in a string of digits where
# a separator should occur. It's code down to its essence, unmarred by garish
# juggling of bits hither and thither.
#
# One example of an algorithmic solution (an amusing one, even):
#
# puts "12345".reverse.scan(/\d{1,3}/).join(".").reverse
#
# This solution also shows one problem with algorithmic code, when compared to
# a formal definition. This code will wreak havok on a mixed string, while the
# regex substitution will handle the occurrences of digits perfectly, without
# damage to its surroundings. (And a contrived example proves any argument.)
# In a way, regexen are similar to SQL queries. What you're doing there is
# coming up with the definition of the particular subset of the data that you
# want. That "SELECT" reads so imperative is an incidental conundrum.
# Thinking in declarative terms is also one of the cornerstones of functional
# programming. The difference between it and imperative programming being
# tantamount to the difference between saying "this is it" and "it's like when
# you do this, and then you do that, and if something then you do this other
# thing, unless …"
# Please consider that:
# • The number of bugs per lines of code is somewhat constant. The more you
# code you use to perform a task, the more bugs you introduce.
# • Typing leads to RSI, which can be excruciatingly painful, which leads to
# not typing anymore. Ever again.
# • Reading code is an onerous task. Overly long code leads pointless
# rewrites, which leads to wankery, more bugs, unemployment, bankruptcy.
#
# Think more so you can type less, read less, and maybe even have a chance at
# eventually producing bug-free code.
#
# With that said, you can listen to everything else jwz has to say.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment