このパートでは、標準入力と簡単な文字列の加工について取り扱います。
レッスン1 標準入力
コンソール版fluorite-7では、組み込み定数IN
に標準入力を1行ずつ読み出すストリーマが格納されています。
$ echo -e 'abc\ndef' | fl7 'IN'
abc
def
IN
はストリーマであるため、パイプでそのまま1行ごとにデータを処理できます。
$ echo -e 'abc\ndef' | fl7 'IN | [_, _]'
abc,abc
def,def
レッスン2 文字列長
長さ演算子$#
で文字列の長さが得られます。
$ fl7 '$#"abcdefg", $#"あ"'
7
1
全角文字も1文字としてカウントされますが、サロゲートペアは2文字としてカウントされます。
標準入力の1行ごとに処理ができるようになって、文字列長の取得という計算が可能になったので、何か処理を行ってみましょう。
cat /etc/nanorc | grep -vE '^#|^$'
というbashコマンドでは以下のような出力が得られました(環境によります)。
$ cat /etc/nanorc | grep -vE '^#|^$'
set historylog
set locking
set nowrap
set suspend
include "/usr/share/nano/*.nanorc"
これにfl7 'IN | $#_'
をくっつけてみましょう。
$ cat /etc/nanorc | grep -vE '^#|^$' | fl7 'IN | $#_'
14
11
10
11
34
set nowrap
が10
に変換されました。
改行を含んでいない文字が_
にやってきているのが分かります。
レッスン3 位置アクセス
「文字列[
位置]
」で、特定の位置にある文字を取り出します。
これをfluorite-7では位置アクセスと呼びます。
$ fl7 '"abcdefg"[4]'
e
負の位置を指定した場合、文字列の末尾から数えた位置の文字を取得します。
-1であれば最後の文字が得られます。
$ fl7 '"abcdefg"[-1]'
g
$ fl7 '"abcdefg"[-7]'
a
レッスン4 部分アクセス
「文字列[
開始位置;
終了位置]
」で文字列の特定の一部分を切り出すことができます。
これをfluorite-7では部分アクセスと呼びます。
切り出される文字は、終了位置にある文字を含みません。
得られる文字列の長さは(終了位置-開始位置)になります。
$ fl7 '"abcdefg"[2; 5]'
cde
終了位置は省略できます。
終了位置を省略すると、文字列の末尾までを切り出します。
$ fl7 '"abcdefg"[2; ]'
cdefg
開始位置を省略すると、文字列の先頭からになります。
$ fl7 '"abcdefg"[; 5]'
abcde
両方省略したらどうなるでしょうか。
$ fl7 '"abcdefg"[; ]'
abcdefg
両方省略すると、文字列の先頭から末尾までを切り出します。
fluorite-7の文字列は不変オブジェクトなので、これをやる意味は特にないです。
こちらも負の位置指定ができます。
$ fl7 '"abcdefg"[-4; -1]'
def
これは末尾から4文字から、末尾から1文字目の手前までを抜き出します。
Tips 配列の切り出し
実は全く同じ指定の仕方が配列でもできます。
$ fl7 '[zero, one, two, three][2]'
two
$ fl7 '[zero, one, two, three][-1]'
three
$ fl7 '[zero, one, two, three][1; 3]'
one,two
$ fl7 '[zero, one, two, three][1; ]'
one,two,three
$ fl7 '[zero, one, two, three][; 3]'
zero,one,two
$ fl7 '[zero, one, two, three][; ]'
zero,one,two,three
$ fl7 '[zero, one, two, three][-3; -1]'
one,two
レッスン5 文字列のストリーマ展開
文字列に対して後置[]
を置くと、文字のストリーマを得ます。
$ fl7 '"abcde"[]'
a
b
c
d
e
1文字ごとに処理を行うことができます。
$ fl7 '"abcde"[] | "[$(_)]"'
[a]
[b]
[c]
[d]
[e]
レッスン6 文字列結合
中置&
は、左右の値を文字列として認識し、結合します。
$ fl7 '"Score: " & 400'
Score: 400
これは埋め込みと似ています。
$ fl7 '"Score: $(400)"'
Score: 400
レッスン7 文字列の繰り返し
中置*
を文字列に対して行うと、その文字列を繰り返します。
$ fl7 '"abc" * 3'
abcabcabc
レッスン8 文字列化・数値化
前置&
は値の文字列化、前置+
は値の数値化を行います。
$ fl7 '&400, +"400"'
400
400
これだけでは分からないので、値の型を見てみましょう。
$ fl7 'TYPE(400), TYPE("400")'
NUMBER
STRING
$ fl7 'TYPE(&400), TYPE(+"400")'
STRING
NUMBER
&400
はSTRING
、+"400"
はNUMBER
となりました。
データの変換が行われていることが分かります。
文字列の数値化は、文字列として格納されている数値を使用して算術を行う際に必須です。
例えば次のコードはどうなるでしょうか。
$ fl7 '"999" + 1'
このような「文字列として格納された数値」と数値の足し算の挙動は、プログラミング言語によってまちまちです。
fluorite-7では、中置+
演算子は、左辺が文字列であれば文字列結合を行います。
$ fl7 '"999" + 1'
9991
この場合、999と1を足した1000を得るには、左辺を明示的に数値化します。
$ fl7 '+"999" + 1'
1000
他にも、数値同士を並べた数値を作るときに文字列の数値化が使えます。
$ fl7 '+(5 & 4 & 3) + 10000'
10543
5 & 4 & 3
はこのままでは文字列なので+ 10000
をすると54310000
という文字列になってしまいますが、5 & 4 & 3
に+
を付けることで543という数値を得て、それに10000を加算したので10543という数値が得られました。
レッスン9 JOIN関数・SPLIT関数
組み込み定数JOIN
には、ストリーマの各要素を文字列化し、,
で結合する関数が入っています。
$ fl7 'JOIN(1 .. 4)'
1,2,3,4
これだけでは配列の文字列化と変わりありません。
$ fl7 '&[1 .. 4]'
1,2,3,4
しかし、JOIN関数は第2引数に結合に使う文字列を受け取れます。
$ fl7 'JOIN(1 .. 4; " / ")'
1 / 2 / 3 / 4
SPLIT関数はJOIN関数とは逆に、1個の文字列を,
で分割し、ストリーマにします。
$ fl7 'SPLIT("1,2,3,4")'
1
2
3
4
SPLIT関数も同様に第2引数で分割文字列を受け取れます。
$ fl7 'SPLIT("1 / 2 / 3 / 4"; " / ")'
1
2
3
4
レッスン10 標準入力からのカラムの選択
前の方で出たこのコマンド出力の、historylog
や"/usr/share/nano/*.nanorc"
の部分を取り出してみましょう。
$ cat /etc/nanorc | grep -vE '^#|^$'
set historylog
set locking
set nowrap
set suspend
include "/usr/share/nano/*.nanorc"
つまり、このような文字列の出力を目指します。
historylog
locking
nowrap
suspend
"/usr/share/nano/*.nanorc"
まずIN
だけを置くと、入力したものを何もせずそのまま出力します。
各行に対して処理を行いたいのでIN
にパイプを付けて行ごとに加工できるようにします。
$ cat /etc/nanorc | grep -vE '^#|^$' | fl7 'IN | _'
set historylog
set locking
set nowrap
set suspend
include "/usr/share/nano/*.nanorc"
_
は恒等変換なので、このままでは入力したものをそのまま出力するだけです。
各行に対して空白で分割したいので、各行に対してSPLIT(_; " ")
を適用します。
SPLIT関数はストリーマを返すので、[
]
で囲んで一旦配列にします。
$ cat /etc/nanorc | grep -vE '^#|^$' | fl7 'IN | [SPLIT(_; " ")]'
set,historylog
set,locking
set,nowrap
set,suspend
include,"/usr/share/nano/*.nanorc"
区切りが,
になりました。あとは添え字1の要素を取得すれば完成です。
$ cat /etc/nanorc | grep -vE '^#|^$' | fl7 'IN | [SPLIT(_; " ")][1]'
historylog
locking
nowrap
suspend
"/usr/share/nano/*.nanorc"
まとめ
-
IN
で標準入力を1行ずつ読み込む。 -
$#string
で文字列長が得られる。 -
string[index]
で文字が得られる。 - 負の位置を指定すると末尾から数える。
-
string[start; end]
で部分文字列が得られる。 - 部分文字列の開始・終了位置は省略できる。
-
string[]
で文字のストリーマを得る。 -
value1 & value2
は文字列として結合する。 -
string * number
で文字列を繰り返す。 -
&value
で文字列化、+value
で数値化する。 -
JOIN
でストリーマを特定の文字列で結合できる。 -
SPLIT
で文字列を特定の文字列で分割してストリーマにできる。