• 検索結果がありません。

ruby3 資料 CSコンピュータ系実験IV RoRによるウェブサイト構築 ruby3

N/A
N/A
Protected

Academic year: 2018

シェア "ruby3 資料 CSコンピュータ系実験IV RoRによるウェブサイト構築 ruby3"

Copied!
6
0
0

読み込み中.... (全文を見る)

全文

(1)

Ruby

簡単入門 第

3

コンピュータ系実験

IV

資料

担当:冨永

今回は入力に便利なARGFと、組み込みクラスRegexp,

Symbol,Hashの使い方について学びます。

1

ARGF

ARGFは、コマンド行引数で指定されたファイルを全て

つなげた文字列を表わします1。コマンド行引数が指定さ

れない場合には、標準入力(キーボード入力)になります。

演習1 試してみよう

次のプログラムは、入力ファイルの内容を全て大文字に して出力する。

ARGF.each do |x|

print x.upcase

end

このプログラム(upcase.rbという名前で作ったとす

る)の入力を、

• ファイ ル ひ と つ を 引 数 と し て 指 定 す る(ruby

upcase.rb ファイル名)

• ファイ ル 複 数 を 引 数 と し て 指 定 す る(ruby

upcase.rb ファイル名1 ファイル名2 …)

• 引数にファイルを指定せず、キーボードから入力す

る(ruby upcase.rb)

の3つのやり方で与えて、正しく動くことを確認せよ。

2

正規表現

正規表現regular expressionとは、文字列の集合を表現

するものです。文字列に合うがら柄(パターンpattern)と考

えればよいでしょう。

コンピュータで使われる正規表現にはいろいろな

種類があります。シェルで使われる「?」(任意の 1 文

1ただしARGFのクラスはStringではありません。eachメソッド

の動作がStringに似ているだけです。

字に合う)や「*」(0 文字以上の任意の文字列に合

う)も正規表現の一種です2。これらは「

*.rb」(a.rb, b.rb, foo.rb,test1.rbなどに合う)や「work.?」

(work.h,work.c,work.yなどに合う)のように使わ

れます。

Rubyの正規表現は斜線「/」で囲って「/· · ·/」の形で 表記します。以下に基本的な正規表現の書き方を説明し ます。

• /./ 任意の1文字に合う

合う文字列の例:a b A 2

• /[abc]/ aとbとcに合う

合う文字列の例:a b c

• /[a-j]/ aからjまでの文字1文字に合う

合う文字列の例:a b k h

• /[A-Za-z]/ 英字1文字に合う

• /[0-9]/ 数字1文字に合う

• /[ˆA-Za-z]/ 英字でない文字1文字に合う

• /.../ 3文字に合う

• /[A-Z]../ 英大文字から始まっている3文字に 合う

• | 選択

/.|../ 1文字と2文字に合う

• * 繰り返し、0回以上

/.*/ 任意の0文字以上の文字列に合う

• ˆ 先頭

/ˆ[A-Z]/ 先頭が大文字

• $ 末尾

/\.$/ 末尾がピリオド

• () 括弧でまとめる

/(ab)*/ λ,ab,abab,. . .

3

使い方その

1

:合うかどうか調べる

以下では変数sは文字列を示しているとします。ただ

しs中に改行文字はないものとします3。

if /[A-Z]/ =˜ s

# sに大文字が入っていれば

何かする

end

2ただしピリオド「.」で始まるファイル名には合わないような工夫 がされています。

(2)

if /this/ =˜ s

# sにthisという文字列が入っていれば

何かする

end

if /ˆ[A-Z]/ =˜ s

# sが大文字で始まっていれば

何かする

end

if /ˆ[A-Z]*$/ =˜ s

# sが大文字だけでできていれば

何かする

end

if /ˆ[01][01]*$/ =˜ s # sが2進数ならば

何かする

end

• =˜ 合うか

合えば、合った部分の先頭の添字

合わなければnil

• !˜ 合わないか

合わなければtrue、合えばfalse

演習2 正規表現を使ってファイル内文字列検索

入力ファイル内にある「his」という文字列を含む行

を全て表示するプログラムを作れ。入力ファイルはARGF

を使って扱うこと。

4

使い方その

2

:合った部分を取り出す

指定した正規表現に合った部分は変数$&に入ります。

s = "I’m 20 years old."

/[0-9][0-9]*/ =˜ s # [0-9]+ でも同じ puts "Your are #{$&} years old."

括弧がある場合には、それぞれの括弧に合った部分が

$1,$2,. . .に入ります。

s = "Taro is a student."

/([A-Za-z]*) is ([A-Za-z ]*)\./ =˜ s puts "Is #{$1} #{$2}?"

合うところが複数ある場合には、最初に少しでも合う ところからできるだけ長くとります。

/[a-z]*/ =˜ "cowboy" # $& #=> "cowboy"

/[a-z]+/ =˜ "This is a pencil."

# $& #=> "his"

/[a-z]*/ =˜ "This is a pencil." # $& #=> ""

演習3 整数をファイルから取り出す

入力ファイルから整数値を取り出して表示するプログラ

ムを作れ。ただし1行に整数は高々1つしかないと仮定

してよい。例えば次のようなファイルを入力として与え ると、

Hello!

I’m 21 years old.

I bought a pen at a 100-yen shop.

Bye!

以下のように表示されるように。

21

100

5

正規表現を使う便利なメソッド

正規表現を使う便利なメソッドは多くありますが、こ

こでは2つだけ紹介します。

5.1

文字列置換

substitution

String#subは、第1引数に指定した正規表現に合う

部分を第2引数の文字列で置き換えます。

"I’m Taro.".sub(/[ˆA-Za-z]/, "XYZ")

#=> "IXYZm Taro."

"I’m Taro.".sub(/[ˆA-Za-z]/, "")

(3)

String#gsubは合う部分すべてを(globally)それぞ

れ置き換えます。

"I’m Taro.".gsub(/[ˆA-Za-z]/, "XYZ")

#=> "IXYZmXYZTaroXYZ"

"I’m Taro.".gsub(/[ˆA-Za-z]/, "")

#=> "ImTaro"

5.2

語の切り出し

String#scan

String#scanは、指定された正規表現が表わす語を

文字列の中から切り出して配列にまとめます。

"Thank you, Tom!".scan(/[A-Za-z]+/)

#=> ["Thank", "you", "Tom"]

"01011001".scan(/./)

#=> ["0","1","0","1","1","0","0","1"]

演習4 伏せ字化

入力ファイル中の自分の名前を全て「XXXXX」という伏

せ字にするプログラムを作れ。

演習5 整数の取り出し(その2

入力ファイル中の整数を全て取り出し、その合計を表示

するプログラムを作れ。ただし1行に複数の整数がある

可能性もあるとする。

6

Symbol

クラス

Symbolクラスのインスタンスはシンボルといいます。

シンボルは文字列と1対1に対応するオブジェクトです。

シンボルは:foobarとか:’foobar’などのリテラル

で得られます。

Stringとの大きな違いは、Stringクラスでは複数

のインスタンスが同じ文字列を表すことがあるのに対し て同じ文字列を表すシンボルはひとつしかないことと、シ

ンボルは変更不可immutableであることです。

s = "hello"

t = "hello"

s.equal?(t) #=> false

s[0] #=> "h"

s[0] = "H"

s #=> "Hello"

x = :hello

y = :hello

x.equal?(y) #=> true

x[0] #=> "h"

x[0] = "H" # エラー

同じ文字列なら必ず同じオブジェクトなので安心して

使えます。Rubyでは次に説明するHashクラスにおける

鍵としてよく使います。

シンボルに.to sするとStringクラスのオブジェク

トが得られます。逆にStringクラスのオブジェクトに

.to symするとシンボルが得られます。

7

Hash

クラス

Hashクラスは、鍵keyキ ー と値valueの対(それらへの参

照)を格納するデータ構造です。「辞書」「マップ」「連想 配列」などとも呼ばれます。

どんなクラスのものでも鍵や値になれます。鍵を指定 すると値を取り出すことができます。

h = Hash.new

# 果物名が鍵、値段が値

h["apple"] = 100

h["kiwi"] = 80

h["mango"] = 200

puts h["apple"] # 100 が表示される

a = [] # 果物の名前 h = {} # 値段

ARGF.each do |x|

/([a-z]+) ([0-9]+)/ =˜ x

a << $1

h[$1] = $2.to_i

end

a.sort.each do |f|

puts "#{f} は #{h[f]} 円です" end

(4)

h = {} # 空のハッシュ p h["foo"] # nil が表示される

8

Hash

リテラル

h = { "apple" => 100,

"kiwi" => 80,

"mango" => 200 }

h["apple"] #=> 100

シンボルを使うと、

h = { :apple => 100,

:kiwi => 80,

:mango => 200 }

h[:apple] #=> 100

Ruby 1.9以降では、シンボルを鍵にする場合には以下

のように書けます。

h = { apple: 100,

kiwi: 80,

mango: 200 }

9

Hash

のメソッド

• key?:指定したものが鍵として登録されているかど

うかを返します。

• keys:全ての鍵を配列にして返します。

• values:全ての値を配列にして返します。

• to a: 全ての対を配列にして返します。ひとつの要

素が大きさ2の配列(第0要素が鍵、第1要素が値)

です。

• each key:それぞれの鍵についてブロックを実行し ます。

• each value:それぞれの値についてブロックを実行 します。

• each:それぞれの鍵と値の対についてブロックを実

行します。ブロック局所変数は|k,v|のように宣言

します。

h = { "apple" => 100,

"kiwi" => 80,

"mango" => 100 }

h.key?("apple") #=> true

h.key?("papaya") #=> false

h.keys

#=> ["apple", "mango", "kiwi"]

h.values

#=> [100, 100, 80]

h.to_a.each do |x|

puts "#{x[0]} は #{x[1]} 円です" end

h.each do |k,v|

puts "#{k} は #{v} 円です" end

演習6 配列からハッシュを作る

100m走の順位を示した配列がある。例えば以下のよ

うなものである。

a = ["Hanako", "Taro", "Jiro"]

この場合Hanakoが1位、Jiroが3位とする。

このような配列aから、名前を鍵として指定すると

順位を返すようなハッシュhを作るコードを示せ。(つ

まり、h["Taro"]とすると整数の2が得られるように

する。)

演習7 ハッシュと配列

単語とその意味をデータとして保持しておき、入力さ れた単語の意味を表示するプログラムを作ることを考え る。単語の意味のデータはプログラム中に定数(リテラ ル)として与えることにする。例えば以下のようなもの を与える。

単語:"apple"

意味:"round fruit with red or green skin"

単語:"kiwi"

意味:"a flightless bird in New Zealand"

単語:"mango"

意味:"a yellowish-red tropical fruit"

そしてキーボードから「kiwi」と入力すると、「a flightless bird in New Zealand」と表示するものとする。

(5)

2.ハッシュを使わずに、配列を使って、このプログラム を実現せよ。

10

インスタンスの複製

インスタンスを複製するにはcloneを使います。

s = "hello!"

t = s.clone # 上の文字列の複製を作る

a = [s, t]

b = a.clone

それぞれのIDを.object idで表示してみましょう。

puts s.object_id

puts t.object_id

puts a.object_id

puts b.object_id

puts a[0].object_id

puts b[0].object_id

cloneは「浅い複製」をします。「深い複製」をしたい

場合には自分でコードを書く必要があります。

演習8 深い複製

aからbへ、配列の要素もそれぞれ複製するような

コードを書け。

11

応用問題

今まで習ってきたRubyの使い方を組み合わせて、少し

高度なプログラムを作ってみましょう。

演習9 データ処理

ある人々の体重の分布を以下のように表わしたファイ ルがある。

30 2

40 4

50 7

60 9

70 6

80 4

90 1

行はそれぞれ、30kg台の人は2人、40kg台の人は4人、

などを表わしている。このようなファイルを与えると、

その階級までの累績人数を3番目の欄として加えて出力

するプログラムを作れ。つまり出力が、

30 2 2

40 4 6

50 7 13

60 9 22

70 6 28

80 4 32

90 1 33

などとなるように。

演習10 ログ処理

あるWWWサーバのアクセス記録ファイルの各行は

次のような形式になっている。

YYYY/MM/DD HH:MM:SS ユーザ名 "アクセスしたファイル"

例えば以下のように。

2007/12/13 23:58:02 taro "/index.html" 2007/12/13 23:59:31 taro "/image/logo.png" 2007/12/13 23:59:42 - "/links/tarotaro.html" 2007/12/14 00:00:39 taro "/links/index.html" 2007/12/14 00:01:06 kotaro "/index.html" 2007/12/14 00:02:25 taro "/index.html"

ユーザ名は英数字から成る。ただしユーザ名「-」は未

登録ユーザを表わすとする。ファイル名には二重引用符 「"」は含まれないとする。

このようなファイルを与えると、ユーザtaroがアク

セスしたファイルの名前とアクセス回数の一覧を次のよ うな形式で出力するプログラムを作れ。

2 /index.html

1 /links/index.html

1 /image/logo.png

演習11 テキスト処理

英文の文章が入っているテキストファイルが与えられ ると、そのファイルにおける各語の出現回数を出力する プログラムを作れ。例えば、

Show your flowcharts and conceal your tables and I will be mystified. Show your tables and your flowcharts will be obvious.

というファイルが与えられたら、

(6)

your 4 flowcharts 2 and 3

conceal 1 tables 2 i 1 will 2 be 2

mystified 1 obvious 1

参照

関連したドキュメント

joint work with Michele D’Adderio and Anna Vanden Wyngaerd 2 september, 2019.. Thank you for

ガイダンス: 5G 技術サプライヤと 5G サービスプロバイダは、 5G NR

Aiming to introduce a general framework, which encompasses most multiscale representation systems developed within the area of applied harmonic analysis, we start by reviewing some

bridge UP, pp. The Movement of English Prose, Longmans. The Philosophy of Grammar. George Allen &amp; Unwin. A Modem English Grammar on Historical Principles, Part IV.

Touchdown Total may be applied as a spot spray in peppermint and spearmint. Apply spray-to-wet with hand-held equipment, such as backpack and knapsack sprayers, pump-up

It guides you through the process of connecting your RSL10 Evaluation and Development Board, installing an IDE and the CMSIS-Pack, configuring your environment, and building

If you disclose confidential Company information through social media or networking sites, delete your posting immediately and report the disclosure to your manager or supervisor,

When placing your order, please inform us of any allergies or special dietary requirements that we should be aware of when preparing your