Ruby

文字列とシンボル

Ruby

String・Symbol・ヒアドキュメント・フォーマット

文字列の基本

作成・補間・メソッド・ミュータビリティ

strings.rb ruby
# 文字列リテラル
single = 'シングルクォート(補間なし)\n は文字通り'
double = "ダブルクォート(補間あり)\n は改行"

# 文字列補間
name = 'Alice'
age  = 30
"こんにちは、#{name}#{age}歳ですね。"
"計算: #{1 + 2 * 3}"  # 式も使える

# ヒアドキュメント
text = <<~HEREDOC
  インデントを除去する
  複数行テキスト
  #{name} さんへ
HEREDOC

# 主なメソッド
s = '  Hello, World!  '
s.strip          # 'Hello, World!'
s.chomp          # 末尾の改行のみ削除
s.upcase         # '  HELLO, WORLD!  '
s.downcase       # '  hello, world!  '
s.capitalize     # '  hello, world!  ' → 'Hello, world!'
s.reverse        # '  !dlroW ,olleH  '
s.length         # 18
s.size           # 18(length の別名)

s.include?('World')    # true
s.start_with?('  H')   # true
s.end_with?('  ')      # true

s.gsub('o', '0')       # 全置換
s.sub('o', '0')        # 最初の1つのみ置換
s.gsub(/\s+/, '_')     # 正規表現で置換

s.split(', ')          # ['  Hello', 'World!  ']
s.split                # 空白で分割

'ab' * 3               # 'ababab'
'a' + 'b'              # 'ab'

# フォーマット
'%s は %d 歳' % [name, age]   # 'Alice は 30 歳'
format('%.2f', 3.14159)       # '3.14'
sprinf('%05d', 42)            # '00042'

シンボル

Symbol vs String・用途・変換

symbols.rb ruby
# シンボル: イミュータブルな名前付き識別子
sym = :hello
:hello.class  # Symbol

# Stringとの違い
:hello.object_id == :hello.object_id  # true(同じオブジェクト)
'hello'.object_id == 'hello'.object_id # false(毎回新しいオブジェクト)

# よく使われる場面
hash = { name: 'Alice', age: 30 }  # キーとしてのシンボル
hash[:name]  # 'Alice'

attr_accessor :name, :email  # メソッド名のシンボル
:upcase.to_proc              # Proc に変換
['a','b','c'].map(&:upcase)  # ['A','B','C']

# 変換
:hello.to_s    # 'hello'
'hello'.to_sym # :hello

# respond_to? / send
'hello'.respond_to?(:upcase)  # true
'hello'.send(:upcase)         # 'HELLO'(メソッドを動的呼び出し)

# Symbol.all_symbols で全シンボルを確認(開発時のみ)

エンコーディングと正規表現

Regexp・match・scan・gsub

regex.rb ruby
# 正規表現リテラル
pattern = /\w+@[\w.]+/

text = 'Alice: alice@example.com, Bob: bob@test.org'

# マッチ確認
text =~ /\w+@\w+/     # マッチ位置(整数)または nil
/\w+@\w+/ === text    # true(case/when でも使える)
text.match?(/\w+@\w+/) # true(MatchData不要)

# MatchData
m = text.match(/(\w+)@([\w.]+)/)
m[0]        # 'alice@example.com'(全体)
m[1]        # 'alice'(グループ1)
m[2]        # 'example.com'(グループ2)

# 名前付きグループ
m = text.match(/(?<user>\w+)@(?<domain>[\w.]+)/)
m[:user]    # 'alice'
m[:domain]  # 'example.com'

# 全マッチ取得
text.scan(/(\w+)@([\w.]+)/)  # [['alice','example.com'],['bob','test.org']]

# 置換
text.gsub(/\w+@[\w.]+/, '[REDACTED]')  # 全置換
text.sub(/\w+/, 'Charlie')             # 最初の1つ
text.gsub(/(?<u>\w+)@([\w.]+)/) { "#{$~[:u]}@hidden.com" }  # ブロックで

# よく使うパターン
/^\d+$/           # 数字のみ
/\A[a-zA-Z0-9_]+\z/ # \A,\z: 文字列全体の先頭・末尾(^,$はマルチライン)
/\p{Hiragana}/    # Unicodeプロパティ(ひらがな)
/\p{Han}/         # 漢字

# フラグ
/hello/i          # 大文字小文字無視
/first.*second/m  # .が改行にもマッチ
/hello # 注釈/x   # 空白・コメント許可(拡張モード)