403e57e2be130d2218f992b86dfa8260

We've had the debate over wether it was a good idea or not to do this.

1
2
3
4
5
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 !

880cbab435f00197613c9cc2065b4f5a

danielharan

October 30, 2007, October 30, 2007 15:40, permalink

No rating. Login to rate!

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 =~

1
2
3
4
5
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
Bfec5f7d1a4aaafc5a2451be8c42d26a

macournoyer

October 30, 2007, October 30, 2007 15:53, permalink

1 rating. Login to rate!

I think {1} are useless, we also can make it case insensitive

1
2
3
4
5
class String 
  def postal?  
    self =~ /[a-z]\d[a-z]([\s-])*\d[a-z]\d/i
 end
end
F6cc8c225523205bb7172c823227da34

Frankie

October 30, 2007, October 30, 2007 15:58, permalink

No rating. Login to rate!

thx everyone here for refactoring this. gary had posted this for me. Very helpful.

880cbab435f00197613c9cc2065b4f5a

danielharan

October 30, 2007, October 30, 2007 16:08, permalink

1 rating. Login to rate!

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!

1
2
3
4
5
class String 
  def postal_code?  
    self.strip =~ /^[a-z]\d[a-z][ -]?\d[a-z]\d$/i
 end
end
0481b9ea2b2aad6844b33dbca2d7fe0e

Paul Kemper

November 5, 2007, November 05, 2007 09:55, permalink

1 rating. Login to rate!

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

63b22ac9bff0cd55d8a91da4dbf00693

Dan Kubb

December 2, 2007, December 02, 2007 16:29, permalink

1 rating. Login to rate!

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.

1
2
3
4
5
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

Your refactoring





Format Copy from initial code

or Cancel