stringproc.lispは、
enlarges
Maximaの文字列を扱う機能を拡大し、
ファイル入出力に関するいくつかの役立つ関数を追加します。
質問とバグに関して、van.nek at arcor.deにメールしてください。
Maximaでは、
文字列は、"text"とタイプすることで簡単に構成することができます。
stringpは文字列かテストします。
(%i1) m: "text"; (%o1) text (%i2) stringp(m); (%o2) true
文字は長さ1の文字列として表されます。
これらはLisp文字ではありません。
テストは
charpで行うことができます。
(関連として、lcharpと
cunlispを使ったLisp文字からMaxima文字への変換)
(%i1) c: "e"; (%o1) e (%i2) [charp(c),lcharp(c)]; (%o2) [true, false] (%i3) supcase(c); (%o3) E (%i4) charp(%); (%o4) true
stringproc.lispの中の、文字を返す関数すべては、Maxima文字を返します。
導入された文字が長さ1の文字列だという事実のおかげで、たくさんの文字列関数を文字にも使うことができます。
既に見たように、
supcaseは1例です。
Maxima文字列の最初の文字は位置1にあることを知ることは重要です。
これは、Maximaリストの中の最初の要素も位置1にあるという事実によって設計されています。
例えば、charatやcharlistの定義を見てください。
応用として、
文字列関数はしばしばファイルを扱う時に使われます。
stringproc.lispの中に役立つストリーム関数、印字関数を見つけるでしょう。
以下の例はここで導入された関数のいくつかがいかに働くか示します。
例:
openwは、ファイルへの出力ストリームを返し、
printfは、このファイルへのフォーマットされた書き込みを可能にします。
詳細はprintfを参照してください。
(%i1) s: openw("E:/file.txt");
(%o1) #<output stream E:/file.txt>
(%i2) for n:0 thru 10 do printf( s, "~d ", fib(n) );
(%o2) done
(%i3) printf( s, "~%~d ~f ~a ~a ~f ~e ~a~%",
42,1.234,sqrt(2),%pi,1.0e-2,1.0e-2,1.0b-2 );
(%o3) false
(%i4) close(s);
(%o4) true
ストリームを閉じた後、今度は入力方向で再び開くことができます。
readlineは行全体を1つの文字列として返します。
現在、stringprocパッケージは
文字列を操作するたくさんの関数を提供しています。
splitやtokensでトークン化できます。
(%i5) s: openr("E:/file.txt");
(%o5) #<input stream E:/file.txt>
(%i6) readline(s);
(%o6) 0 1 1 2 3 5 8 13 21 34 55
(%i7) line: readline(s);
(%o7) 42 1.234 sqrt(2) %pi 0.01 1.0E-2 1.0b-2
(%i8) list: tokens(line);
(%o8) [42, 1.234, sqrt(2), %pi, 0.01, 1.0E-2, 1.0b-2]
(%i9) map( parse_string, list );
(%o9) [42, 1.234, sqrt(2), %pi, 0.01, 0.01, 1.0b-2]
(%i10) float(%);
(%o10) [42.0, 1.234, 1.414213562373095, 3.141592653589793, 0.01,
0.01, 0.01]
(%i11) readline(s);
(%o11) false
(%i12) close(s)$
ファイルの終わりに来ると、
readlineはfalseを返します。
例:
(%i1) s: openw("E:/file.txt");
(%o1) #<output stream E:/file.txt>
(%i2) control:
"~2tAn atom: ~20t~a~%~2tand a list: ~20t~{~r ~}~%~2t\
and an integer: ~20t~d~%"$
(%i3) printf( s,control, 'true,[1,2,3],42 )$
(%o3) false
(%i4) close(s);
(%o4) true
(%i5) s: openr("E:/file.txt");
(%o5) #<input stream E:/file.txt>
(%i6) while stringp( tmp:readline(s) ) do print(tmp)$
An atom: true
and a list: one two three
and an integer: 42
(%i7) close(s)$
streamを閉じて、
もしstreamが開いていたら
trueを返します。
streamの中の要素の数を返します。
もしposが使われてないなら、
streamの中の現在位置を返します。
もしposが使われているなら、
fpositionはstreamの中の位置を設定します。
posは正の数でなければいけません。
streamの最初の要素は位置1にあります。
(streamに)改行を書きます。
newline()の使用の例に関しては、
sprintを参照してください。
newline()が期待通りに動かない
いくつかの場合があることに注意してください。
fileへの出力ストリームを返します。
もし存在しているファイルを開いたら、
openaはファイルの終わりに要素を追加します。
fileへの入力ストリームを返します。 もしfileが存在しないなら、生成されます。
fileへの出力ストリームを返します。
もしfileが存在しないなら、生成されます。
もし存在しているファイルを開いたら、openwは
fileを破壊的に変更します。
Common Lisp関数FORMATをMaximaで利用可能にします。 (gcl.infoから: 「フォーマットは 制御文字列の文字を出力し、波形記号がディレクティブを挿入することを守ることで、 フォーマットされた出力を生成します。 波形記号の後の文字は多分、前置パラメータと修飾語が先行し、 望まれるフォーマットの種類を指定します。 ほとんどのディレクティブは、出力を生成するために1つまたは複数の引数を使います。」)
以下の記述と例はprintfを使うアイデアを与えるかもしれません。
さらなる情報に関して、Lisp参考文献を参照してください。
~% 改行
~& 行のフレッシュ
~t タブ
~$ 通貨記号
~d 10進整数
~b 2進整数
~o 8進整数
~x 16進整数
~br b進整数
~r 整数を一字一字
~p 複数形
~f 浮動小数点
~e 科学的記数法
~g 大きさに応じて~fまたは~e
~h 多倍長浮動小数点
~a Maxima関数文字列を使う
~s ~aと同様, しかし"ダブルコーテーション"で囲まれた出力
~~ ~
~< 行揃え, ~> 終端
~( 大文字小文字変換, ~) 終端
~[ 選択, ~] 終端
~{ 繰り返し, ~} 終端
選択ディレクティブ~[は添字がゼロから始まることに注意してください。
ディレクティブ~*がサポートされていないことにも注意してください。
(%i1) printf( false, "~a ~a ~4f ~a ~@r",
"String",sym,bound,sqrt(12),144), bound = 1.234;
(%o1) String sym 1.23 2*sqrt(3) CXLIV
(%i2) printf( false,"~{~a ~}",["one",2,"THREE"] );
(%o2) one 2 THREE
(%i3) printf(true,"~{~{~9,1f ~}~%~}",mat ),
mat = args(matrix([1.1,2,3.33],[4,5,6],[7,8.88,9]))$
1.1 2.0 3.3
4.0 5.0 6.0
7.0 8.9 9.0
(%i4) control: "~:(~r~) bird~p ~[is~;are~] singing."$
(%i5) printf( false,control, n,n,if n=1 then 0 else 1 ), n=2;
(%o5) Two birds are singing.
もしdestがストリームかtrueなら、
printfはfalseを返します。
そうでないなら、printfは出力を含む文字列を返します。
streamの現在位置から行の終わりまでの文字を含む文字列か、 もしファイルの終わりが来たらfalseを返します。
引数を順に評価し、一番左から始まる「一行」に表示します。
数は数の右隣に’-’と共に印字され、行の長さを無視します。
もし中間行ブレークを置きたいなら、
newline()―stringproc.lisp から自動ロードされます―
が役に立つかもしれません。
例:
(%i1) for n:0 thru 19 do sprint( fib(n) )$
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
(%i2) for n:0 thru 22 do (
sprint(fib(n)), if mod(n,10)=9 then newline() )$
0 1 1 2 3 5 8 13 21 34
55 89 144 233 377 610 987 1597 2584 4181
6765 10946 17711
もしcharがアルファベット文字ならtrueを返します。
もしcharがアルファベット文字か数字ならtrueを返します。
ASCIIコードint( -1 < int < 256 )に対応する文字を返します。
(%i1) for n from 0 thru 255 do (
tmp: ascii(n), if alphacharp(tmp) then sprint(tmp),
if n=96 then newline() )$
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
もしchar_1とchar_2が同じならtrueを返します。
cequalと同様ですが、文字の大小を無視します。
もしchar_1のASCIIコードがchar_2のそれより大きいならtrueを返します。
cgreaterpと同様ですが、文字の大小を無視します。
もしobjがMaxima-文字ならtrueを返します。
例えばイントロダクションを参照してください。
charのASCIIコードを返します。
もしchar_1のASCIIコードがchar_2のそれより小さいならtrueを返します。
clesspと同様ですが、文字の大小を無視します。
もしcharがグラフィック文字であり、スペース文字でないなら、
trueを返します。
グラフィック文字は見ることができる文字とスペース文字です。
(constituentは、Paul Graham, ANSI Common Lisp, 1996, page 67で定義されています。)
(%i1) for n from 0 thru 255 do (
tmp: ascii(n), if constituent(tmp) then sprint(tmp) )$
! " # % ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B
C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c
d e f g h i j k l m n o p q r s t u v w x y z { | } ~
Lisp文字をMaxima文字に変換します。 (必要としないでしょう。)
もしcharが0から9までの数字なら、
trueを返します。
もし objがLisp文字なら、trueを返します。
(必要としないでしょう。)
もしcharが小文字なら、trueを返します。
改行文字。
スペース文字。
タブ文字。
もしcharが大文字なら、trueを返します。
もしobjが文字列なら、trueを返します。
例はイントロダクションを参照してください。
stringのn番目の文字を返します。 stringの一番目の文字はn = 1で返されます。
(%i1) charat("Lisp",1);
(%o1) L
stringの文字すべてのリストを返します。
(%i1) charlist("Lisp");
(%o1) [L, i, s, p]
(%i2) %[1];
(%o2) L
文字列strをMaxima式としてパースし、評価します。
文字列strは終端子(ドル記号$またはセミコロン;)
を持つかもしれませんし持たないかもしれません。
もし複数あるなら、最初の式だけがパースされ、評価されます。
もしstrが文字列でないならエラーが出力されます。
例:
(%i1) eval_string ("foo: 42; bar: foo^2 + baz");
(%o1) 42
(%i2) eval_string ("(foo: 42, bar: foo^2 + baz)");
(%o2) baz + 1764
parse_stringも参照してください。
文字列strをMaxima式としてパースします(評価しません)。
文字列strは終端子(ドル記号$またはセミコロン;)
を持つかもしれませんし持たないかもしれません。
もし複数あるなら、最初の式だけがパースされ、評価されます。
もしstrが文字列でないならエラーが出力されます。
例:
(%i1) parse_string ("foo: 42; bar: foo^2 + baz");
(%o1) foo : 42
(%i2) parse_string ("(foo: 42, bar: foo^2 + baz)");
2
(%o2) (foo : 42, bar : foo + baz)
eval_stringも参照してください。
stringのコピーを新しい文字列として返します。
supcaseと同様ですが、大文字が小文字に変換されます。
もしstring_1とstring_2が同じ長さで、同じ文字を含むなら、
trueを返します。
sequalと同様ですが、文字の大小を無視します。
sexplodeは関数charlistの別名です。
simplodeは式のリストを取り、それらを結合して文字列にします。
もしデリミタdelimが指定されないなら、
simplodeはデリミタを使いません。
delimは任意の文字列を取り得ます。
(%i1) simplode(["xx[",3,"]:",expand((x+y)^3)]);
(%o1) xx[3]:y^3+3*x*y^2+3*x^2*y+x^3
(%i2) simplode( sexplode("stars")," * " );
(%o2) s * t * a * r * s
(%i3) simplode( ["One","more","coffee."]," " );
(%o3) One more coffee.
substring (string, 1, pos - 1)と
文字列seq、substring (string, pos)
の結合となる文字列を返します。
stringの一番目の文字は位置1にあることに注意してください。
(%i1) s: "A submarine."$
(%i2) concat( substring(s,1,3),"yellow ",substring(s,3) );
(%o2) A yellow submarine.
(%i3) sinsert("hollow ",s,3);
(%o3) A hollow submarine.
位置startからendまでのそれぞれの文字を逆順にすることを除いて stringを返します。 もしendが与えられないなら、 startから stringの終わりまでのすべての文字列が置き換えられます。
(%i1) sinvertcase("sInvertCase");
(%o1) SiNVERTcASE
stringの中の文字の数を返します。
num個の文字charを持つ新しい文字列を返します。
(%i1) smake(3,"w"); (%o1) www
string_1とstring_2が異なるstring_1の最初の文字の位置、または
falseを返します。
マッチングのデフォルトのテスト関数はsequalです。
もしsmismatchが文字の大小を無視なければいけないなら、
テストとしてsequalignoreを使ってください。
(%i1) smismatch("seven","seventh");
(%o1) 6
stringのすべてのトークンのリストを返します。
それぞれのトークンはパースされていない文字列です。
splitはdelimをデリミタとして使います。
もしdelimが与えられないなら、
スペース文字がデフォルトのデリミタです。
multipleはデフォルトでtrueのブーリアン変数です。
重複デリミタが1つとして読まれます。
これは、
もしタブが複数スペース文字として保存されているなら、
役立ちます。
もしmultipleがfalseに設定されるなら、
それぞれのデリミタが有効です。
(%i1) split("1.2 2.3 3.4 4.5");
(%o1) [1.2, 2.3, 3.4, 4.5]
(%i2) split("first;;third;fourth",";",false);
(%o2) [first, , third, fourth]
stringの中で、charとマッチする最初の文字の位置を返します。
stringの一番目の文字は位置1にあります。
文字の大小を無視した文字のマッチに関しては,
ssearchを参照してください。
string同様文字列を返しますが、
seqとマッチする部分文字列すべてなしに返します。
マッチのデフォルトのテスト関数はsequalです。
もしsremoveがseqを検索する間文字の大小を無視しなければいけないなら、
テストとしてsequalignoreを使ってください。
探索を限定するにはstartとendを使ってください。
stringの一番目の文字は位置1にあることに注意してください。
(%i1) sremove("n't","I don't like coffee.");
(%o1) I do like coffee.
(%i2) sremove ("DO ",%,'sequalignore);
(%o2) I like coffee.
seqとマッチする最初の文字列だけが削除されることを除いて、
sremove同様です。
stringの文字すべてが逆順の文字列を返します。
文字列seqとマッチするstringの最初の部分文字列の位置を返します。
マッチのためのデフォルトのテスト関数はsequalです。
もしssearchが文字の大小を無視しなければいけないなら、
テストとしてsequalignoreを使ってください。
検索を限定するには、startとendを使ってください。
stringの一番目の文字は位置1にあることに注意してください。
(%i1) ssearch("~s","~{~S ~}~%",'sequalignore);
(%o1) 4
test (c, d)がfalse、かつ、test (d, c)がtrueであるような2つの連続する文字cとdがないような順で
stringの文字すべてを含む文字列を返します。
ソートのためのデフォルトのテスト関数はclesspです。
テスト関数一式は{clessp, clesspignore, cgreaterp, cgreaterpignore, cequal, cequalignore}です。
(%i1) ssort("I don't like Mondays.");
(%o1) '.IMaddeiklnnoosty
(%i2) ssort("I don't like Mondays.",'cgreaterpignore);
(%o2) ytsoonnMlkIiedda.'
stringの中のoldにマッチするすべての部分文字列を
newで置き換えた文字列を返します。
oldとnewは同じ長さである必要はありません。
マッチのためのデフォルトのテスト関数はsequalです。
もしssubstがoldを検索する間大文字小文字を無視すべきなら、
テストとしてsequalignoreを使ってください。
検索を制限するには、startとendを使ってください。
stringの一番目の文字は位置1にあることに注意してください。
(%i1) ssubst("like","hate","I hate Thai food. I hate green tea.");
(%o1) I like Thai food. I like green tea.
(%i2) ssubst("Indian","thai",%,'sequalignore,8,12);
(%o2) I like Indian food. I like green tea.
oldとマッチする最初の部分文字列だけを置き換えることを除いて、
substと同様です。
stringの両端からseqに現れるすべての文字を除いた文字列を返します。
(%i1) "/* comment */"$
(%i2) strim(" /*",%);
(%o2) comment
(%i3) slength(%);
(%o3) 7
stringの左端だけトリムすることを除いて
strimと同様です。
stringの右端だけトリムすることを除いて
strimと同様です。
位置startで始まり位置endで終わる stringの部分文字列を返します。 位置endの文字は含まれません。 もしendが与えられないなら、部分文字列は文字列の残りを含みます。 stringの一番目の文字は位置1にあることに注意してください。
(%i1) substring("substring",4);
(%o1) string
(%i2) substring(%,4,6);
(%o2) in
stringの位置startからendまでの小文字を対応する大文字に置き換えた 文字列を返します。 もしendが与えられないなら、 startからstringの終わりまでのすべての小文字が置き換えられます。
(%i1) supcase("english",1,2);
(%o1) English
stringから抽出されたトークンのリストを返します。
トークンは、文字があるテスト関数を満たす部分文字列です。
もしテストが与えられないなら、
constituentがデフォルトテストとして使われます。
{constituent, alphacharp, digitcharp, lowercasep, uppercasep, charp, characterp, alphanumericp}はテスト関数一式です。
(The Lisp-version of
tokensのLispバージョンはPaul Grahamによって書かれました。 ANSI Common Lisp, 1996, page 67.)
(%i1) tokens("24 October 2005");
(%o1) [24, October, 2005]
(%i2) tokens("05-10-24",'digitcharp);
(%o2) [05, 10, 24]
(%i3) map(parse_string,%);
(%o3) [5, 10, 24]