From: "Michael W. Ryder" <_mwryder@...> Date: 2007-07-20T17:34:58+09:00 Subject: Re: Is there a replacement for sub? Robert Klemme wrote: > 2007/7/20, Michael W. Ryder <_mwryder@worldnet.att.net>: >> Morton Goldberg wrote: >> > On Jul 19, 2007, at 11:00 PM, Michael W. Ryder wrote: >> > >> >> I was trying to come up with a way to remove x instances of a >> >> character from a string and came up with a problem. If I enter: >> >> >> >> a = "a b c d e f" >> >> for i in 1..3 >> >> a = a.sub!(' ', '') >> >> end >> >> puts a ==> returns 'abcd e f' which is correct. >> >> >> >> But if I enter: >> >> >> >> a = "a b c d e f" >> >> for i in 1..10 >> >> a = a.sub!(' ', '') >> >> end >> >> puts a ==> returns error.rb:3: private method `sub!' called for >> >> nil:NilClass (NoMethodError, and a is now nil. >> >> >> >> What I am looking for is a way to remove the first n instances of a >> >> blank from the string without wiping out the string if it does not >> >> contain at least n blanks. I assume there is a way to do this with >> >> regular expressions, but have not found it yet. This is something an >> >> editor I liked, UCEDIT, on the CDC Cyber had in the 70's. >> > >> > How about this? >> > >> > n = 3 >> > "a b c d e f".sub(/(\S\s){#{n}}/) { |m| m.delete(" ") } # => "abcd e f" >> > n = 10 >> > "a b c d e f".sub(/(\S\s){#{n}}/) { |m| m.delete(" ") } # => "a b c >> d e f" >> > >> > Regards, Morton >> > >> >> Is there nothing in regular expressions where you can tell it to do >> something up to n times? > > There is - kind of. You can use {} to give repetition counts. You can > do this > > irb(main):004:0> a = "a b c d e f" > => "a b c d e f" > irb(main):005:0> a.sub(/(?: [^ ]*){3}/) {|m| m.gsub(/ /, '') } > => "abcd e f" > irb(main):006:0> > > Kind regards > > robert > Unfortunately this is much more complicated and much harder to understand, and debug. The editor I mentioned had an argument you passed to the expression that told it to do it one time if it was absent, n number of times, or till the end. Since this was 30 years ago I expected that something like this hadn't been dropped in the interim.