4

给定以下缩进文本:

  two spaces
    four
      six
non-leading    spaces

我想将每 2 个前导空格转换为一个制表符,本质上是从软制表符转换为硬制表符。我正在寻找以下结果(使用“x”而不是“\t”):

xtwo spaces
xxfour
xxxsix
non-leading  spaces

在 ruby​​ 中执行此操作的最有效或最有说服力的方法是什么?

到目前为止,我似乎正在工作,但感觉不对。

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;

红宝石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 回答