バイオインフォ道場、くまぞうです。
文字列処理は、スクリプトを書く時に活用する機会の多い処理です。整形や文字列の連結処理・正規表現を使った部分文字列の処理などが使えるようになると、処理を簡潔に書くことができるようになるかもしれません。代表的なものを整理してみましょう。
Rubyの文字列
文字列とは、いくつかの文字を組み合わせたものです。文字列は、Stringクラスのオブジェクトです。従って、様々な便利なメソッドを使って演算を行うことができます。Rubyで文字列を扱うのはとても簡単です。
よく使う操作
リテラル
文字列のリテラルは""
(ダブルクォーテーション)で囲むか、''
(シングルクォーテーション)で囲むか、です。便利な式展開と組み合わせることが多いので、通常は前者で対応します。
書式付きの表示
書式付き表示を使うと、数値の整形やフィールド幅の調整を行うことができます。情報を分り易く、キレイに表示することができます。
str1.rb
#! /usr/bin/ruby # 数値整形 printf "%%d %d\n", 10 # %d 10進表示 printf "%%x %#x\n", 10 # %x 16進表示 printf "%%b %#b\n", 10 # %b 2進表示 printf "%%f %f\n", 10 # %f 小数表示 # まとめて表示 puts "%%d %%x %%b %%f = %d %#x %#b %f" % Array.new(4, 10)
%d 10 %x 0xa %b 0b1010 %f 10.000000 %d %x %b %f = 10 0xa 0b1010 10.000000
str2.rb
#! /usr/bin/ruby # フィールド幅と精度 printf ('-'*6)+"\n" # 6桁 printf "%6s\n", "abc" # 6桁で右詰(文字) printf "%-6s\n", "abc" # 6桁で左詰(文字) printf "%6d\n", 100 # 6桁で右詰(整数) printf "%06d\n", 100 # 6桁で右詰・0埋め(整数) printf "%6.2f\n", 12.3 # 6桁幅で、小数点以下2桁
$ str2.rb ------ abc abc 100 000100 12.30
式展開
#{式}
を使うことで、""
(ダブルクォーテーション)で囲まれた文字内で変数・式を展開することができます。
test3.rb
#! /usr/bin/ruby # 式展開 aaa = 100 puts "number = #{aaa}" puts "number = #{aaa+=1}" you = ARGV[0] bbb = "hello" you ||= "world" puts "#{bbb} #{you} !!"
$ ruby str3.rb WORLD number = 100 number = 101 hello WORLD !!
正規表現とパターンマッチ
正規表現を使ってパターンマッチを行うには、=~
を使います。リテラルを用いて評価することが多いです。正規表現には色々な構文があります。よく使う文字クラスやグループ・アンカーなどを覚えると良いと思います。正規表現を使うと、パターンマッチした部分文字列やその前後などが簡単に取り出せるので便利です。
よく使う正規表現とパターンマッチ
-
.
文字1つにマッチ。他の表現と組合せて使うことが多い。 -
\w
単語の構成要素 -
\s
空白文字。[ \t\n\r\f]と同じ意味。 -
\d
数字。[0-9]と同じ意味。 -
a|b
aまたはb -
re{n,m}
reのn回以上m回以下の繰り返し。{n}で回数指定、{n,}でn回以上。 -
^
行の先頭 -
$
行の末尾 -
(re)
グループ化。マッチしたものについて、$1, $2…でアクセスできる。
str4.rb
#! /usr/bin/ruby aaa = "hello world" puts " target: #{aaa}" puts # 基本的なパターンマッチ puts " reg exp: \/ll\/" pos = (aaa =~ /ll/) puts " match: \"#{aaa[pos..(pos+2)-1]}\"" puts " pre_match: #{$~.pre_match}" puts "post_match: #{$~.post_match}" puts # 繰り返しを利用したパターンマッチ puts " reg exp: \/l{2,}\/" pos = (aaa =~ /l{2,}/) puts " match: \"#{aaa[pos..(pos+2)-1]}\"" puts " reg exp: \/l{1,2}\/" pos = (aaa =~ /l{1,2}/) puts " match: \"#{aaa[pos..(pos+2)-1]}\"" puts # アンカーを利用したパターンマッチ puts " reg exp: \/^h\/" pos = (aaa =~ /^h/) puts " match: \"#{aaa[pos]}\"" # 先頭 puts " reg exp: \/^H\/i" pos = (aaa =~ /^H/i) puts " match: \"#{aaa[pos]}\"" # 大文字・小文字無視 puts # グループを利用したパターンマッチ puts " reg exp: \/\(.*\)\\s\(.*\)\\.\/" "hello world." =~ /(.*)\s(.*)\./ # 空白前後で単語に分ける puts " match1: \"#{$1}\"" puts " match2: \"#{$2}\""
$ str4.rb target: hello world reg exp: /ll/ match: "ll" pre_match: he post_match: o world reg exp: /l{2,}/ match: "ll" reg exp: /l{1,2}/ match: "ll" reg exp: /^h/ match: "h" reg exp: /^H/i match: "h" reg exp: /(.*)\s(.*)\./ match1: "hello" match2: "world"
文字列の連結
文字列と文字列を+
や<<
演算子で連結したり、式展開などの演算結果として結合することもできます。
str5.rb
#! /usr/bin/ruby # 連結 puts "aaa"+"bbb" aaa = "AAA"; bbb = "BBB" puts aaa+bbb # 文字列に直接追加 aaa << bbb ccc = "aaa --change--> #{aaa}" puts ccc
$ ruby str5.rb aaabbb AAABBB aaa --change--> AAABBB
部分文字列・置換・改行空白
文字列を構成する文字1つ1つには、配列のようにインデックスを使ってアクセスすることができます。また、部分文字列として切り出したり、文字列を挿入・置換することができます。その他、改行・空白処理もよく行いますが、便利なメソッドを使うと簡単に処理することができます。
str6.rb
#! /usr/bin/ruby # 部分文字列へのアクセス puts "target=" + (aaa = "hello world") puts puts "start: #{aaa[0]}" # 先頭文字 puts "end : #{aaa[-1]}" # 末尾の文字 puts "range: #{aaa[6..-1]}" # 部分文字列(範囲) puts puts "split" puts "[" + aaa.split.join(", ") + "]" puts puts "insert" aaa.insert(6, "! ") puts aaa puts puts "change" aaa[0]='H' # 置き替え puts aaa
$ ruby str6.rb target=hello world start: h end : d range: world split [hello, world] insert hello ! world change Hello ! world
str7.rb
#! /usr/bin/ruby # いろんな置換 puts (aaa = "hello world") puts puts aaa.tr('o', 'O') # 指定した文字を全て置換 puts aaa.sub('l', 'L') # 指定した文字を最初のものだけ置換 puts aaa.gsub('l', 'L') # 指定した文字・文字列を全て置換
$ ruby str7.rb hello world hellO wOrld heLlo world heLLo worLd
str8.rb
#! /usr/bin/ruby # -*- coding:utf-8 -*- # 改行処理 aaa = "hello\n" # 改行付き bbb = "world\n" # 改行付き printf "%s %s\n", aaa.chomp, bbb.chomp # chompで改行処理を行う printf "%s %s\n", *([aaa, bbb].map &:chomp) # chompで改行処理を行う(同じ) puts # 空白処理 puts "|" + " hello ".strip + "|" # 前後の空白文字を削除 puts "|" + " hello ".lstrip + "|" # 左側だけ削除 puts "|" + " hello ".rstrip + "|" # 右側だけ削除
$ ruby str8.rb hello world hello world |hello| |hello | | hello|