From: RichardOnRails Date: 2009-11-13T16:35:06+09:00 Subject: Re: DRYing a Regex Hey Caleb & James, With your insights, I was able to cut down 18 lines of somewhat obscure code to 6 lines that I find very readable. That's such and improvement on the quality of the code. Though I expect you guys are tired ot this thread, I included the new and old code below, along with results that both of them produce. Again, thank you very much for your insights. Best wishes, Richard # Accept a new list as a string; extract an array of contiguous upper- case letters as stock symbols, ignoring any duplicates (Test data) # Delete any symbol in the current list that occurs here sNewList = %{TMxxx CSCO COL INTC BRCM FDX AA CAT BUR FSLR MSFT', PNC HPQ CSCO AMAT ORCL FCX ABX PVTB XHB CSCO TM FDX} #=============== # New technique #=============== aRawNewList = sNewList.scan(/[A-Z]+/) aNewList = Set.new(aRawNewList ).to_a.sort nDeleted = 0 aNewList.each { |sym| hCurrentList.delete sym and nDeleted += 1 if hCurrentList[sym] } show_array( aNewList, 10, "New List (unique:%d, dups:%d, deleted:%s)" % [aNewList.size, aRawNewList.size - aNewList.size, nDeleted] , true) #============================ # Old technique; No longer used #============================ aNewList = [] s = StringScanner.new sNewList upper = /[A-Z]+/ non_upper= Regexp.new( upper.source.sub( /\[/, '[^' ) ) nNewSyms = nCurrSymsDeleted = 0 while not s.eos? case when s.skip(upper) nNewSyms+=1 aNewList << s.matched unless aNewList.include? s.matched ( hCurrentList.delete s.matched and nCurrSymsDeleted += 1) if hCurrentList[s.matched] else s.skip(non_upper) end end show_array( aNewList.sort, 10, "New List (%d unique; %d dups; %d curr. deleted)" % [aNewList.size, nNewSyms - aNewList.size, nCurrSymsDeleted] ) #======= # Output #======= ===== New List (unique:19, dups:4, deleted:3) ===== AA ABX AMAT BRCM BUR CAT COL CSCO FCX FDX FSLR HPQ INTC MSFT ORCL PNC PVTB TM XHB ===== =====