4

次のインデントされたテキストがあるとします。

  two spaces
    four
      six
non-leading    spaces

2つの先頭のスペースごとにタブに変換したいのですが、基本的にはソフトタブからハードタブに変換します。次の結果を探しています(「\ t」の代わりに「x」を使用):

xtwo spaces
xxfour
xxxsix
non-leading  spaces

ルビーでこれを行うための最も効率的または雄弁な方法は何ですか?

私が今まで持っていたものは機能しているようですが、それは正しく感じられません。

input.gsub!(/^ {2}/,"x")
res = []
input.split(/\n/).each do |line|
  while line =~ /^x+ {2}/
    line.gsub!(/^(x+) {2}/,"\\1x")
  end
  res << line
end
puts res.join("\n")

sedと\Gを使用して答えに気づきました:

perl -pe '1 while s/\G {2}/\t/gc' input.txt >output.txt

しかし、Rubyでパターンを模倣する方法がわかりません。これは私が得た限りです:

rep = 1
while input =~ /^x* {2}/ && rep < 10
  input.gsub!(/\G {2}/,"x")
  rep += 1
end
puts input
4

2 に答える 2

4

(?:^ {2})|\G {2}複数行モード で使用することの何が問題になっていますか?

最初の一致は常に行の先頭にあり、
\ Gはそのすぐ隣で連続して一致します。そうでない場合、一致
は失敗します。次の試合は常に行の先頭になります。繰り返します。

Perlではその$str =~ s/(?:^ {2})|\G {2}/x/mg;または$str =~ s/(?:^ {2})|\G {2}/\t/mg;

Ruby http://ideone.com/oZ4Os

input.gsub!(/(?:^ {2})|\G {2}/m,"x")

編集: もちろん、アンカーを除外して交互に入れることができます
http://ideone.com/1oDOJ

input.gsub!(/(?:^|\G) {2}/m,"x")
于 2012-05-15T23:51:29.873 に答える
2

そのために単一のgsubを使用できます。

str.gsub(/^( {2})+/) { |spaces| "\t" * (spaces.length / 2) }
于 2012-05-15T23:32:36.930 に答える