From: Josef 'Jupp' Schugt Date: 2003-06-01T04:04:51+09:00 Subject: Re: expandtabs Saluton! * Steven Shaw, 2003-05-30, 21:05 UTC: > The methods for expanding tabs in the Ruby FAQ don't seem to work. > def method1(a) > 1 while a.sub!(/(^[^\t]*)\t(\t*)/){$1+' '*(8-$1.size%8+8*$2.size)} > a > end > > def method2(a) > 1 while a.sub!(/\t(\t*)/){' '*(8-$~.begin(0)%8+8*$1.size)} > a > end > > def method3(a) > a.gsub!(/([^\t]{8})|([^\t]*)\t/n){[$+].pack("A8")} > a > end > > def println(s) > print s, "\n" > end > > string = "" > (0..10).each {|n| > string << "blah\t" + (" " * n) + "blah\n" > } > > println(method1(string.clone)) > println(method2(string.clone)) > println(method3(string.clone)) I did already answer that in a PM. The above works correct but does not have the intended result. The problem is that the sample string does contain "\n" characters. The easiest solution would be using string.split("\n").each{|x| println(method1(x))} string.split("\n").each{|x| println(method2(x))} string.split("\n").each{|x| println(method3(x))} in place of the given calls of println. Nevertheless it would be better to reset the length counting for each "\n". The following is a quick'n'dirty hack that does this in a way that is far from optimal. def method4(a) b = '' l = 1 0.upto(a.length) { |i| case a[i] when 9 b += ' ' l += 1 while l % 8 != 0 b += ' ' l += 1 end when 10 b += a[i..i] l = 1 else b += a[i..i] l += 1 end } return b end A shorter solution is: def method1(a) a.split("\n").each {|b| 1 while b.sub!(/(^[^\t]*)\t(\t*)/){$1+' '*(8-$1.size%8+8*$2.size)} b }.join("\n") end The equivalents for method2 and method3 are obvious. Does anybody have a better solution that does not require splitting and re-joining (which is time-consuming)? Gis, Josef 'Jupp' Schugt -- e-mails that do not contain plain text, are larger than 50 KiB, are unsolicited, or contain binarys are ignored unless payment from your side or technical reasons give rise to a non-standard treatment. Schroedinger's cat is not alive.