challenge /*コメント*/を取り除く

与えられた文字列から「/*」と「*/」で挟まれた部分を取り除くコードを書いてください。

なお、「/*」と入力末尾で挟まれた部分も取り除いてください。 つまり、入力が「AAA/*BBB」なら出力は「AAA」です。 また、コメントは入れ子になりません。入力が「AAA/*BBB/*CCC*/DDD*/EEE」のとき、ひとつめの「*/」でコメントが終わるので出力は「AAADDD*/EEE」になります。 「//」や「**」が混ざる場合の挙動は失敗しやすいので要注意です。

Pythonでの実行例は下のようになります:

>>> remove_comment('AAA')
'AAA'
>>> remove_comment('AAA/*BBB*/')
'AAA'
>>> remove_comment('AAA/*BBB')
'AAA'
>>> remove_comment('AAA/*BBB*/CCC')
'AAACCC'
>>> remove_comment('AAA/*BBB/*CCC*/DDD*/EEE')
'AAADDD*/EEE'
>>> remove_comment('AAA/a//*BB*B**/CCC')
'AAA/a/CCC'

このお題は匿名での投稿を参考にして作成しました。 ありがとうございます。

Posted feedbacks - Ruby

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def remove_comment(str)
  str.gsub(%r!/\*(.+?)(\*/|$)!, "")
end

remove_comment('AAA')           # => "AAA"
remove_comment('AAA/*BBB*/')    # => "AAA"
remove_comment('AAA/*BBB')      # => "AAA"
remove_comment('AAA/*BBB*/CCC') # => "AAACCC"
remove_comment('AAA/*BBB/*CCC*/DDD*/EEE') # => "AAADDD*/EEE"
remove_comment('AAA/a//*BB*B**/CCC') # => "AAA/a/CCC"

これでいいんじゃないかな?
1
2
3
def remove_comment(str)
  str.gsub(/\/\*.*?(\*\/|\z)/,"")
end

既出のHaskellコードのアルゴリズムを拝借してRubyで書いてみた。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def remove_comment(str)
  def off_comment(cs, rs)
    return rs.join unless(cs);
    if ((cs[0] == "/") && (cs[1] == "*"))
      on_comment(cs[2..(cs.length - 1)], rs);
    else    
      off_comment(cs[1..(cs.length - 1)], rs.push(cs[0]));
    end
  end

  def on_comment(cs, rs)
    return rs.join unless(cs);
    if ((cs[0] == "*") && (cs[1] == "/"))
      off_comment(cs[2..(cs.length - 1)], rs);
    else    
      on_comment(cs[1..(cs.length - 1)], rs);
    end
  end

  off_comment(str.split(//), []);
end

いつもこんな風に書いてる。
1
2
3
def remove_comment(txt)
  txt.gsub(/\/\*.*?\*\//m, '')
end

ぁ。行末処理…
1
2
3
def remove_comment(txt)
  txt.gsub(/\/\*.*?(\*\/|$)/, '')
end

$ より \z の方がそれっぽい出力ではないですかね。私は\z ばかりで $ は滅多に使わないのですが。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class String
  def remove_comment
    self.gsub(/\/\*.*?(\*\/|\z)/m, '')
    #self.gsub(/\/\*.*?(\*\/|$)/m, '')
  end
end

str = DATA.readlines.join
print str.remove_comment
__END__
code
/*
comment
*/
code

なんかイビつだなぁ><
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def remove_comment(str="")
  m = str.match(/\/\*/)
  if m.nil?
    puts str
    return
  end
  print m.pre_match
  
  m = m.post_match.match(/\*\//)
  unless m.nil?
    print m.post_match
  end
  puts
end

remove_comment('AAA')
remove_comment('AAA/*BBB*/')
remove_comment('AAA/*BBB')
remove_comment('AAA/*BBB*/CCC')
remove_comment('AAA/*BBB/*CCC*/DDD*/EEE')
remove_comment('AAA/a//*BB*B**/CCC')

gsub一行で実装してるのを見ると悔しくなるので、自分でも実装してみた。
正規表現の部分とか人によって違う結果になるかなと思ったけど、他の人と同じ正規表現になっちゃったな。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def remove_comment(str = "")
  str.gsub(/\/\*.*?(\*\/|\z)/,"")
end

puts remove_comment('AAA')
puts remove_comment('AAA/*BBB*/')
puts remove_comment('AAA/*BBB')
puts remove_comment('AAA/*BBB*/CCC')
puts remove_comment('AAA/*BBB/*CCC*/DDD*/EEE')
puts remove_comment('AAA/a//*BB*B**/CCC')

例をこなすだけなら、gsub は sub でもいいし、\z は $ でもいいし、m オプションはなくてもいいですね。
1
2
3
def remove_comment(str)
  str.gsub(%r!/\*.*?(\*/|\z)!m, '')
end

Index

Feed

Other

Link

Pathtraq

loading...