Ruby 文字列処理 正規表現,部分文字列,置換,連結 スクリプトの書き方

バイオインフォ道場、くまぞうです。

文字列処理は、スクリプトを書く時に活用する機会の多い処理です。整形や文字列の連結処理・正規表現を使った部分文字列の処理などが使えるようになると、処理を簡潔に書くことができるようになるかもしれません。代表的なものを整理してみましょう。

スポンサーリンク



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|
スポンサーリンク