class String
def postal?
self.match(/[a-zA-Z]{1}\d{1}[a-zA-Z]{1}([\x20-])*\d{1}[a-zA-Z]{1}\d{1}/) ? true : false
end
end
Refactorings
No refactoring yet !
danielharan
October 30, 2007, October 30, 2007 15:40, permalink
That ternary operator is not strictly necessary, since any MatchData object will evaluate to true. If no match exists, nil is returned. Another option is to use =~
class String
def postal?
self =~ /[a-zA-Z]{1}\d{1}[a-zA-Z]{1}([\x20-])*\d{1}[a-zA-Z]{1}\d{1}/
end
end
macournoyer
October 30, 2007, October 30, 2007 15:53, permalink
I think {1} are useless, we also can make it case insensitive
class String
def postal?
self =~ /[a-z]\d[a-z]([\s-])*\d[a-z]\d/i
end
end
Frankie
October 30, 2007, October 30, 2007 15:58, permalink
thx everyone here for refactoring this. gary had posted this for me. Very helpful.
danielharan
October 30, 2007, October 30, 2007 16:08, permalink
Now that I'm looking at that regexp, I notice the () that aren't necessary. Also wondering if it helps to add ^ and $, and whether the * should be replaced by a ?
In any case, to answer your initial question: this seems like a good direction. It's easy to go too far, or use this type of code where ActiveRecord Validations are more appropriate. If it helps capture a common pattern and makes your code more readable, I say go for it!
class String
def postal_code?
self.strip =~ /^[a-z]\d[a-z][ -]?\d[a-z]\d$/i
end
end
Paul Kemper
November 5, 2007, November 05, 2007 09:55, permalink
Note that Canadian postal codes cannot start with any letter. Only [ABCEGHJKLMNPRSTVXY] are allowed as starting letters. So your regex would turn into /^[ABCEGHJKLMNPRSTVXY]\d[a-z][ -]?\d[a-z]\d$/i
Dan Kubb
December 2, 2007, December 02, 2007 16:29, permalink
According to http://en.wikipedia.org/wiki/Canadian_postal_code the letters D, F, I, O, Q, or U are excluded because OCR equipment used for automatic mail sorting confuses them with other letters and digits. The letters W and Z are also used, just not in the first character.
If you're storing this in a DB or anything, I would suggest normalizing it so that all the characters are uppercase, leading/trailing spaces are stripped, and a space (not a hyphen) is used between the first 3 characters and the last 3 characters.
class String
def postal?
self.strip.upcase =~ /\A[A-CEGHJ-NPR-TVXY]\d[A-CEGHJ-NPR-TV-Z][ -]?\d[A-CEGHJ-NPR-TV-Z]\d\z/
end
end
Peggy
November 25, 2011, November 25, 2011 00:03, permalink
You really found a way to make this whole porcses easier.
ERROR_BAD_DUPLICATES
We've had the debate over wether it was a good idea or not to do this.