トップページ⇒tech
115コメント43KB

文字列処理に最適な言語

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2007/11/18(日) 07:39:36
定型のテキスト変換処理で、特定の処理しかしないプログラムを組む場合、
CやC++やJAVAは面倒なだけだよね。

かといって、エディタの変換処理やGUIアプリケーションだと
一々操作をしなくちゃなんないので面倒だ。
マクロを組むのも煩雑になりがちだし、偶に機能が足らない時がある。
凄く大変な思いをするよね。

perlなんかも良い感じなんだけど、文字列処理に特化したもっと簡単な言語無いかな。
それに、ASCIIならperl最高なんだけど、日本語が絡むとごちゃごちゃしてくるよね。
「A」と「A」の対応とか。

理想は、コマンドラインやテキストファイルからデータを受け取って、
書いたコードの通りに変換してファイルに出力してくれるような物。
簡単なデータベースも扱えるレベルが良い。

そんな処理言語ないでしょうか。
0002デフォルトの名無しさん2007/11/18(日) 07:44:49
要するに単発質問スレなわけね?
0003デフォルトの名無しさん2007/11/18(日) 07:53:23
具体的には

・perlみたいなオブジェクト指向は要らない。
もっと簡単でMS-DOSバッチコマンドの様な感覚で使える奴が良い。
VBAやWSHは煩雑すぎます。もっと簡単なの。

・メニューも要らない。
出力結果だけが出せればいい。

・文法が簡単。
すぐに覚えられる方が良い。

・UTF-8やSJISやEUC、そのほか、他国語2バイトコードを扱いやすい形で処理。

・スクリプト言語
デバッグがしやすい

・他のプログラムから利用できる
内部ルーチンとしてコマンドラインから呼び出す。
他の言語で同じ処理を組むより簡単で速く組め、バグも少なく、移植性が高くて便利。


こんな感じの要件です。
0004デフォルトの名無しさん2007/11/18(日) 08:01:29
朝からすごいスレに遭遇してしまった・・・
0005デフォルトの名無しさん2007/11/18(日) 08:23:30
>>1氏ね
単発質問糞スレ立てるなカス
こっちで聞け
http://pc11.2ch.net/test/read.cgi/tech/1193556424/
ここは削除依頼出しとけ
0006デフォルトの名無しさん2007/11/18(日) 08:32:47
特定の変換処理っつーと、sed とか AWK とかか?
日本語が絡むとなると Ruby が日本語対応してるのでいいかと。
0007デフォルトの名無しさん2007/11/18(日) 09:11:59
正規表現で2バイト文字限定の . があればと思ったことがある
0008デフォルトの名無しさん2007/11/18(日) 09:40:21
Ruby なら [^\x00-\x7F] とか。
0009デフォルトの名無しさん2007/11/18(日) 09:42:52
SAS、これ最強。価格も最強
0010デフォルトの名無しさん2007/11/18(日) 11:28:43
? 何で SAS が出てくんの?
0011デフォルトの名無しさん2007/11/18(日) 11:56:41
Perlでいいだろ
0012デフォルトの名無しさん2007/11/18(日) 14:08:52
awk
0013デフォルトの名無しさん2007/11/18(日) 14:09:17
PerlでもRubyでもいいんじゃない
0014デフォルトの名無しさん2007/11/18(日) 14:20:17
>・perlみたいなオブジェクト指向は要らない。
じゃあPerl4でもつかっとけよ(w
0015デフォルトの名無しさん2007/11/18(日) 14:55:48
パピルスに戻れや糞が
0016デフォルトの名無しさん2007/11/18(日) 15:05:17
lisp
0017デフォルトの名無しさん2007/11/18(日) 15:13:07
sed, awkに触れないで単発スレ立てとな…
1に殺意を覚えるわ…
0018デフォルトの名無しさん2007/11/18(日) 15:18:09
>>1
おとなしくCOBOLでもかじってろ。
0019デフォルトの名無しさん2007/11/18(日) 16:22:31
SNOBOL は?
0020デフォルトの名無しさん2007/11/18(日) 16:58:07
xyzzyの置換+clispスクリプト
0021デフォルトの名無しさん2007/11/18(日) 18:59:12
python
0022デフォルトの名無しさん2007/11/18(日) 19:22:17
Ruby以外考えられん
0023デフォルトの名無しさん2007/11/18(日) 21:33:06
文脈自由的な構造が、そのプログラム言語の
構文要素で自然に表現(定義)できる言語。
0024デフォルトの名無しさん2007/11/18(日) 21:46:52
そんな何でも切れるナイフみたいなのは要らない
刺身を作るなら刺身包丁
0025デフォルトの名無しさん2007/11/18(日) 21:48:32
>>24
正規表現では >>23 は無理。
0026デフォルトの名無しさん2007/11/18(日) 21:55:39
>>25
は?
0027デフォルトの名無しさん2007/11/18(日) 22:15:34
>>25
蕎麦を切るのには蕎麦切り包丁使うから良いよ
0028262007/11/18(日) 22:20:43
24のレスに25のレスは不可解だと思ったが、そもそも23のレスに24のレスが不可解だったからスレしなおす。

>>24
はぁ?
0029デフォルトの名無しさん2007/11/18(日) 22:27:30
一番カネになるのはCOBOLだと思うぜ。
一番ソンするのはRubyだとおもうぜ。
0030デフォルトの名無しさん2007/11/18(日) 22:50:19
文字列処理に最適な言語を1が作るぞっていうスレかと思った
0031デフォルトの名無しさん2007/11/18(日) 23:03:42
>>28
つまんないよ
0032デフォルトの名無しさん2007/11/18(日) 23:16:57
>>31
はぁ?
0033デフォルトの名無しさん2007/11/18(日) 23:35:53
がっかりだ…
0034デフォルトの名無しさん2007/11/18(日) 23:39:19
自分で面白くしようとしないが、他人には高いハードルを飛べとほざくバカががっかりしてるようです。

コマンド?
0035デフォルトの名無しさん2007/11/18(日) 23:42:51
ハードルが高く感じるなら無理に飛ばなくて良いよ!
0036デフォルトの名無しさん2007/11/18(日) 23:47:32
バカか。跳んで無いだろ。つまんないやつだなお前。
0037デフォルトの名無しさん2007/11/18(日) 23:50:11
親切にしたら仕返しされた
しかもレスに工夫が全然ない
0038デフォルトの名無しさん2007/11/18(日) 23:51:34
アホがつぶやいている。

どうやら俺の設定したハードルは高すぎて飛べなかったようだ。無能確定。
0039デフォルトの名無しさん2007/11/18(日) 23:53:54
幻が見えると楽しいでしょうね!
リアルではお気をつけて
0040デフォルトの名無しさん2007/11/19(月) 00:00:40
アホがまたつぶやいた。

どうやら、幻を見てる男の幻を見てるらしい。

彼がお花畑から脱出するのはいつの日だろうか。
0041デフォルトの名無しさん2007/11/19(月) 00:06:46
flex/bison を文字列処理に使えるかな。
0042デフォルトの名無しさん2007/11/19(月) 00:07:27
↓何かレスすると何の工夫も無い鸚鵡返しのレスが返ってくるスレ
0043デフォルトの名無しさん2007/11/19(月) 00:09:03
             ∩___∩
             |ノ⌒  ⌒ ヽ
             / ●)  ●) |
オツカレチャ━━━━━|   ( _●_)  ミ━━━━━ン♪
            彡、  |∪| 、`
              /  ヽノ  ヽ
             / 人    \\   彡
           ⊂´_/  )    ヽ__`⊃
                / 人 (
               (_ノ (_)
0044デフォルトの名無しさん2007/11/19(月) 00:10:38
30分以上楽しませてあげれたようでよかったです。
0045デフォルトの名無しさん2007/11/19(月) 00:12:57
○ 2点
0046デフォルトの名無しさん2007/11/19(月) 00:13:18
(2点満点中)
0047デフォルトの名無しさん2007/11/19(月) 00:14:40
>>46
ちょっと面白かったw

おやすみ
0048デフォルトの名無しさん2007/11/19(月) 00:15:50
そもそもバカにレスの工夫をしてあげる必要は一切無い。バカには理解できないんだから・・・。
0049デフォルトの名無しさん2007/11/19(月) 00:18:19
>>47
ほら、自分が楽しくなればそれで終わりだ。

自分本位のわがまま自己中バカ。他人とかかわるな。一生寝てろ。
0050デフォルトの名無しさん2007/11/19(月) 05:19:08
>>23 は(正規表現に頼る傾向のある言語に対して)
構造を持った定義の必要な文字列検索だってあるでしょうと言っているのだし、
>>24 はそんな(万能の)出刃包丁は、刺身(少量で高速な文字列処理)には使いません、
といっている。
>>25 はそれに対して、はっきり正規表現を持ち出して、
正規表現には限界があるから、それを超える文字列検索を要求されたら
困るのでは、ということを言っている。

>>25 の表現は適切ではないが、全体としては特に奇異なところは
ないと思う。
0051デフォルトの名無しさん2007/11/19(月) 05:22:57
うん
0052デフォルトの名無しさん2007/11/19(月) 07:04:21
・cobol
・ruby
・sed
・awk
・clisp
・python
・SNOBOL 

色々出ましたが、一番簡単で覚えやすい言語ってどれでしょう?
すごく横着な質問だと思いますが、覚え易さが普及率にも関わってくる
訳で、そうなると、それを覚えていれば長い事使えて、
投資が無駄にならなくて済むなと思うので。

最近流行のrubyなんかは興味があります。
日本人が作ってると言うことで、日本語対応もしっかりしていると思われます。
Cobolは業務用組み込みで普及しているようですが、将来性という点で
どうなのでしょうか?
sedやawkはUNIX標準コマンドだと思いますが、機種依存オプションや
EUC、SJIS、UNICODEの相互対応でコードが煩雑になりそうな感じが気になります。
pythonは世界で普及しているとのことで興味がありますが、
perlと同じように非日本語圏の開発でコード変換の問題を抱えてそうなのが難点ですね。
テキスト処理言語としてなので、その点には拘ってみたいところです。
0053デフォルトの名無しさん2007/11/19(月) 07:18:16
>>52
本当に文字列処理にしか使わないのなら、
一番簡単で覚えやすい言語はPrologでしょう。
要するに >>23 ですね。
3時間で完全に習得できますから。
ただ、それをあなたの周りの標準言語として
普及したいのだとすると、難しいでしょう。
私なら Ruby かな。
0054デフォルトの名無しさん2007/11/19(月) 07:34:52
ありがとうございます。
Prologは確かに覚えやすそうです。論理構造が明快ですし。
ツリー構造や集合などを表現するのには適切かもしれませんね。
しかし、テキスト処理には少し荷が重い様に感じます。
もう少し単純な方が良いです。
主に、置換やマッチや基本的な条件分岐で、
大抵は順を追って処理してくれればいい訳なので。
基本的には手続き型言語の範囲で収まると思います。
あるいは、データベースを元に、ヒューリスティック解析ルーチンを
サブとして組み込む場合に呼び出して判定させたりするなどという
使い方もアリですね。

やはり、今回はrubyを勉強してみます。
0055デフォルトの名無しさん2007/11/19(月) 07:46:03
あと、なぜ、文字コードや機種依存に拘るかというと、
まずWindows上で組んでプログラムを拡張していき、完成した後、
多少の改良をしてUNIXサーバ上で自動処理させたいからです。
主に日本語ファイル名のファイルを管理するので、コードの問題は重要なのです。

将来的にはデータベース処理させる機能も含んだ中小規模のアプリです。
0056デフォルトの名無しさん2007/11/19(月) 11:04:12
INTERCAL最強。
0057デフォルトの名無しさん2007/11/19(月) 17:34:38
オブジェクト指向が嫌なのにRubyなんてありえない

悪いことは言わないからリアルワールドで人を探して相談しなさい
0058デフォルトの名無しさん2007/11/19(月) 19:40:14
>>55
なんで最初からUn*x使わないの?
デュアルブートとかVMでBSDでも動かせば良いじゃん
0059デフォルトの名無しさん2007/11/20(火) 00:03:05
>>55
つーか、素直に最初からDB使えば?
0060デフォルトの名無しさん2007/11/20(火) 19:18:31
>>58
主にエディタがWindowsの方が使い慣れているからです。
他にもファイラーなどの色々なWindowsGUIアプリと作業を連携させたい
と思っています。
一部の自動化できる部分をUNIX側に投げて、手動操作が必要な
部分はWindowsクライアントから作業します。

>>59
既存のDBだと大がかりすぎて管理コストが掛かりすぎますし、
他のアプリを呼び出すなどの連携がいまいち使いにくいのです。
ファイルによって数種類のアプリを使い分けますので。
また、臨機応変にインストールや切り替えを行います。
なのでWindowsの拡張子判別実行やファイラーの類似機能の方が使いやすいのです。

もともと、業務用のテキストや数値データを扱うようにできているので
連携がおろそかになりがちです。
DBとファイルを併用しても良いんですが、そうするとDBとの
同期処理が複雑になりますので現実的ではありません。
0061デフォルトの名無しさん2007/11/20(火) 19:25:33
Unix機のファイルシステムをSambaで共有して、編集だけWindows上の
エディタでやるのがいいと思う。
0062デフォルトの名無しさん2007/11/20(火) 19:28:37
サーバをWindowsにしてしまって、純Windowsで開発してしまえば
コード変換や処理系の混在もなく、話は早いのですが、UNIXは
コマンドラインからの遠隔操作がしやすいので、UNIXを使用しています。
いちいちサーバ室に移動してモニタを確認して再起動や設定を行うのも面倒ですし。
VNCを使って強引に運用しても良いのですが、そもそもWindowsが
遠隔操作用のサーバとして作られていない(Serverを除いて)ので
色々な制限によって非常に使いづらい思いをさせられると思います。
個人なのでServerを買うほどのマニアでもないのでw
0063デフォルトの名無しさん2007/11/20(火) 19:34:33
>>61
はい。そのようにしています。
ただ、そうすると、UNIX側で管理用のDBの生成を行わせた場合、
EUCのファイル名で管理していますから、EUCでリストが生成される
と思います。それを管理ファイルとしてWindows側からも利用しますから、
そこでSJIS変換をして照合という作業が必要になります。
この場合、漢字コード変換をDBの更新毎に繰り返すことになると思います。
また、マッチの不具合では、原因が漢字コード変換にあるのか、
それともソースに矛盾があるのか解らなくなって、
デバッグが複雑になって混乱しがちになると思います。
そういったような煩雑性を上手く回避できる手段はないだろうかと思っているのですが。

それとも、これは漢字コードの根本に関わる問題なんでしょうか。
0064デフォルトの名無しさん2007/11/21(水) 07:58:26
>>62
サーバ室は台所の床板の下にでもあるのかなぁ。
0065デフォルトの名無しさん2007/11/21(水) 10:31:59
私も一階が事務所、二階が自宅。開発や操作は二階の自分の部屋で
している。あなたと条件が違うのは、私の場合は全部Linuxでサーバ。
クライアントはそのうち、メールサーバになってるマシンを使って
いる。全部EUCなので漢字コードの問題はほとんど発生しないけれど、
外部からFTP経由で入ってくるファイルだけはSJISファイル名で困る。
仕事でやりとりするファイルはSJISのCSVやXLSも多いから、データの
入出力時にknfや自作のeuctosjis,sjistoeucでコード変換をせざるを
得ない。
0066デフォルトの名無しさん2007/11/21(水) 14:17:22
良いですね。EUCで統一できるのが理想なんですが。
WinがEUCにならないかなw
グラフィックやCADデータや動画を編集したり色んなビューアーで
見たり組み合わせたりするのでWindowsのソフトを利用したいなと思ってます。
この方面はWindowsが優れていますから。

しかし、漢字コードが統一されてないって大変ですよねぇ。
ファイル名の指定一つでも問題が生じる。
ぶっちゃけ、未だに日本は、アメリカで言えばASCIIの無い
時代みたいなモンなんですかねぇ。
この国のコンピューター文化は未だに20年以上前のアメリカの域に
すら達してないのかもしれませんな。
UNIXが普及しないこと、連携ができないこと、
ほぼ1社のOSに依存すること、技術が蓄積しないこと、
様々な弊害を産み出していると思いますな。
0067デフォルトの名無しさん2007/11/21(水) 14:25:26
しかし、、、1の内容からは全く推測できない仕様だったな
0068デフォルトの名無しさん2007/11/22(木) 02:00:14
FTPなんか使うのやめて
うpろだ立てろ
んでファイル名はそこで変換
UNICODEに一本化
0069デフォルトの名無しさん2007/11/22(木) 09:23:48
Windowsの人はファイル名にスペースを入れる人が多い。
"Program Files" みたいな見本があるから。
これも気楽にsplitで区切ろうとするとき不便。いちいちcutではねぇ。
0070デフォルトの名無しさん2007/11/22(木) 19:47:45
Javaもサロゲートペアがサポートされて1文字16bitが保障できなくなった。
VCでいうstrlenと_mbslenの使い分けの時代がJavaにも来てしまったわけだ。
第4水準漢字が日の目を見るのは純粋に日本人として嬉しいから対応するけどさ。
0071デフォルトの名無しさん2007/11/23(金) 07:21:06
以下にPrologのsplit述語の定義を示します。
split('',_,[]) :- !.
split(Atom,Divs,X) :-
    sa(Atom,AtomL,Divs,Div,AtomR),
    split(AtomL,Divs,LL),
    split(AtomR,Divs,LR),
    append(LL,[Div|LR],X).
split(Atom,Divs,[Atom]) :-
    not(sub_atom_2(Atom,AtomL,Divs,Div,AtomR)).

sa(Atom,AtomL,Divs,Div,AtomR) :-
    member(Div,Divs),
    sub_atom(Atom,Sp,Len,RLen,Div),
    sub_atom(Atom,0,Sp,_,AtomL),
    sub_atom(Atom,Sp + Len,RLen,_,AtomR).
これで
?- split(abcdefgh,[bc,b,ef],X).
X = [a,bc,d,ef,gh];
X = [a,b,cd,ef,gh];
X = [a,bc,d,ef,gh];
X = [a,b,cd,ef,gh];
no.
のような実行結果が得られます。
0072デフォルトの名無しさん2007/11/23(金) 07:41:54
>>71
8行目に not(sub_atom_2(... とありますが not(sa( ... の間違いでした。
最後に読みやすいように短縮したのですが置換し忘れました。

CSVファイルの解析などでは区切り文字は除去したい場合があります。
X = [a,d,gh] のような解が欲しいときですね。この場合は、
上の定義の6行目の
append(LL,[Div|LR],X). を append(LL,LR,X). に変えるだけです。
saという述語のDivという引数も不要にはなりますが。
それでは置換はどうしましょう。
一つの考え方として、Divs(区切り文字候補)に置換情報をふかすると
いうのがあります。[[bc,xx],[b,zz],[ef,u]] というぐあいに。
そして、sa述語の定義の1-2行目を
sa(Atom,AtomL,Divs,Div2,AtomR) :-
  member([Div,Div2],Divs),
に変えるだけです。述語名が split sa ではまずいので、
それぞれ、replace sa_1 に書き換えましょう。
0073デフォルトの名無しさん2007/11/23(金) 07:43:14
replace('',_,[]) :- !.
replace(Atom,Divs,X) :-
    sa(Atom,AtomL,Divs,Div,AtomR),
    replace(AtomL,Divs,LL),
    replace(AtomR,Divs,LR),
    append(LL,[Div|LR],X).
 Atom,Divs,[Atom]) :-
    not(sa_1(Atom,AtomL,Divs,Div,AtomR)).

sa_1(Atom,AtomL,Divs,Div2,AtomR) :-
    member([Div,Div2],Divs),
    sub_atom(Atom,Sp,Len,RLen,Div),
    sub_atom(Atom,0,Sp,_,AtomL),
    sub_atom(Atom,Sp + Len,RLen,_,AtomR).
これで置換の定義ができました。
0074デフォルトの名無しさん2007/11/23(金) 07:48:49
ここからが本題なのですが、
Divsと言う引数に[[bc,xx],[b,zz],[ef,u]]のようにリストとして渡しました。
しかしこれは別のやり方があります。
bb/xx.
b/zz.
ef/u.
のような述語として定義する方法です。この定義が書いてある
ファイルをスクリプトファイルとして、その最終行に何を実行したいか述べます。
>>73 の定義をそれ用に作り替えます。
0075デフォルトの名無しさん2007/11/23(金) 07:59:32
>>73 の7行目 先頭からreplace( が消えてしまっていますね。訂正して読んでください。

replace('',[]) :- !.
replace(Atom,X) :-
    sa(Atom,AtomL,Div,AtomR),
    replace(AtomL,LL),
    replace(AtomR,LR),
    append(LL,[Div|LR],X).
 replace(Atom,[Atom]) :-
    not(sa_1(Atom,AtomL,Div,AtomR)).

sa_1(Atom,AtomL,Div2,AtomR) :-
    Div/Div2,
    sub_atom(Atom,Sp,Len,RLen,Div),
    sub_atom(Atom,0,Sp,_,AtomL),
    sub_atom(Atom,Sp + Len,RLen,_,AtomR).

Divsという引数は不要になったので削りました。Divという引数名も
不適切ですが、以前のコード比較しやすいように残しました。
0076デフォルトの名無しさん2007/11/23(金) 08:15:55
ファイル置換(InStream,OutStream) :-
  see(Instream),tell(OutStream),
  repeat,read_line(X),(X=end_of_file;
  replace(X,Y),concat_atom(Y,Z),
  write(Z),nl,fail),
  seen,told.
replace sa_1 ファイル置換 定義をProlog起動時に予めしておいて、さらに、
以下のようなスクリプトファイルをファイルによる述語定義として実行します。

東京/東京都.
大阪/大阪府.
京都県/京都府.

:- ファイル置換(foo,foo_out).
0077デフォルトの名無しさん2007/11/24(土) 06:16:35
>>71から>>76は
重複解の問題を克服できていないので、正しいプログラムとは
いえないようだ。効率も頗る悪い。今、読み直して気づいた。
ここで示したかったのはPrologがどうのということではない。他の
言語でもそれほど差なくこんなことは書ける。そうではなくて、
文字列処理に最適な言語を問う場合、このようなスクリプトを解析
する定義をどのくらい簡単に書けるかがその評価基準になるのであって、
あるプログラム言語がどのくらい文字列を洗練された記法で扱えるか
ではないということを主張するべく、プログラムコードで表したかった。
たとえば、split を replace に作り替えていく課程で、この言語は
どの程度、文字列処理向きだなと漸く解るのだ。
私のPrologのスーパー述語 sub_atom/5 (/5は引数の数) による定義は
失敗におわった。他の言語でのこういった事例を見たい。
0078デフォルトの名無しさん2007/11/24(土) 07:07:12
split処理のコードを全く書いたことのない人には何がポイントかが
解りにくいと思うので解説します。仕様の問題ともいえるのですが、
区切り文字列候補が [abc,b,bcd] のように重複する部分があると
この処理コードは大変複雑になり、区切り文字を含む解モードでは
非決定性のアルゴリズム(プログラム)になります。具体的にいうと、
頭から、abcが見つかったとして、それ以後の文字列を処理してしまうと
bcdのd部分を見失ってしまうということです。それ以後ではなくabcを
含んだそれ以後の文字列を対象にしなくてはなりません。しかもそこで
いきなり現れるabcは無視して2文字目以降に[abc,c,bcd]が現れるか
調べますが、今度はa+bcd+...のaをどう処理すればよいかの問題も生じます。
abcdを区切り文字と見なして良いのなら事前にそう作り替えておけば
済みますが。Prologのsub_atom/5はこの問題を一述語でやってしまうので、
splitに初めて使ってみましたが、そんなにうまくはいきませんでした。
詳しくは知りませんが一般には、split の区切り候補にこのような重複を
含むことを仕様で禁じることでこの問題を回避しているのではないかと
思います。
0079デフォルトの名無しさん2007/11/24(土) 08:07:58
つまり、Prologで書くと、こんなに空気が読めない自分語りになっちゃうと言うことですね。(Y/y)
0080デフォルトの名無しさん2007/11/24(土) 08:13:05
UNIX文化: 人が機械にあわせる
Windows文化: 機械が人にあわせる
0081デフォルトの名無しさん2007/11/24(土) 08:39:26
逆だろ
0082デフォルトの名無しさん2007/11/24(土) 08:55:44
>>79
そうね。アプリケーションの数だけ最適なのスクリプトがあるから、
その解析部を書かねばならないということをいいたいだけなんだ
けど、なんとかコードで示そうとしていつも失敗する。
0083デフォルトの名無しさん2007/11/24(土) 09:10:41
パイプで繋いで、フォークしてっていうのがUNIX文化でしょ。
機械にあわせるってところは全くないね。人間の知恵の範囲内。
0084デフォルトの名無しさん2007/11/24(土) 09:22:16
オブジェクト指向が差分プログラミグに徹しようよという生活運動だと
すると、論理プログラミングは考えてることとコードを近づけようよと
いう運動と言うことになる。結構何とかなるかなと思って書いてみるが、
掲示板の枠の限界もあってなかなか・・。
0085デフォルトの名無しさん2008/03/22(土) 12:22:19
んー、少なからず全部自力で習得できるとは思えないから
日本語のコミュニティが活発そうな
Ruby
Python
あたりじゃないかな?

個人的にはRubyでやってみたら?とおすすめしておきます
0086デフォルトの名無しさん2008/04/12(土) 17:35:15
私もPrologだな。制御構造がなく、
ワンパターンの再帰プログラムで
データとプログラムがまさに一体で
文字列処理が進んでいく言語は
他にはないですね。
0087デフォルトの名無しさん2008/04/13(日) 16:05:26
Schemeの再帰は基本的なトコだけなら理解出来たんだが
Prologはどれだけやっても組めない…。
0088デフォルトの名無しさん2008/04/13(日) 20:20:53
>>87 Prologによる文字列処理のパターン
p([],[]).
p([A,B|R],[C|R2]) :- q(A,B,C),p(R,R2). /* 一字目(A)と二字目(B)からコンテンツ(C)を得る */
p([_|R],X) :- p(R,X).
q(あ,い,愛).
q(い,ろ,色).

第二節の表現とテーブルqの定義をふくらませるだけ。
文字列比較の時はpの引数が増える。
0089デフォルトの名無しさん2008/08/30(土) 06:05:56
Prologは引数を関数的に評価しないんだよね。受け取ったまま
の姿で単一化しようとする。
それでA+BのA,B双方がStringと分かっていてもこれを結合することが
できない。LL言語の使用者などから見るとそこに違和感ありという
ことになる。
0090デフォルトの名無しさん2008/09/01(月) 09:15:48
Prologは文脈自由なサブ言語を自在に定義できるから、
文字列処理に於いてもLL言語より上位言語と言えるのだろうが、
フォーマルウェアを着込んでる感じ。
LL言語がプレタポルテだとするとオートチュクール。
街を歩くなら、やはり、プレタポルテの服。
0091デフォルトの名無しさん2008/09/01(月) 11:33:53
>>90
プレタポルテの服、どれも同じに見えるんだね。正規表現におんぶ。
0092902008/09/01(月) 14:06:46
アレレ、ミスパンチ。オートクチュールだ。
0093デフォルトの名無しさん2008/09/01(月) 14:28:06
凹凸クール。つまり、縮緬は涼しいってことですね、判ります。
0094デフォルトの名無しさん2008/09/01(月) 15:00:37
なつかしいことばがでてきたなw
0095デフォルトの名無しさん2008/09/20(土) 13:11:22
正規表現をある言語で定義した場合、そのコードがどの程度正規表現の
解説になっているかで、文字列処理の適性度が示されるのではないか。
この観点からはやはりPrologが一位だと思う。
0096デフォルトの名無しさん2008/09/22(月) 12:00:40
>>95
それは読みやすい言語というだけのことだと思う。
文字列の"処理"とは関係がないのでは。
0097デフォルトの名無しさん2008/09/30(火) 20:45:32
テキストの指定された行の頭にコメント記号を付加するコード書いてください
0098デフォルトの名無しさん2008/10/01(水) 10:17:13
>>97
Prologはファイル処理は得意でないから、ライブラリに頼ってる。
ファイルfoo.txt の'メイショウサムソン'という文字列が存在する行頭に
今日の日付をコメントとして付けるには、
?- 今日(_今日),
行置換('foo.txt',A,B,(sub_atom(A,_,_,_,メイショウサムソン),
concat_atom(['/* ',_今日,' */ ',A],B))).

でよいが、最初の適合行だけコメントするというような仕様だと
行置換/4のソースを一部変更した別述語を作る必要がある。
0099デフォルトの名無しさん2008/10/01(水) 15:38:27
>>98では行置換/4を使ったが、行番号が第二引数にくる行置換/5を使うことが多い。
foo.txtの内容が、
1234
acdb
ubaz
yyyy
だとして、
?- 行置換('foo.txt',G,A,B,member([G,B],[[2,aaaa],[5,uuuu]])).
が実行されると、2行目と5行目だけが置換されて、foo.txtは、
1234
aaaa
ubaz
uuuu
となる。
0100デフォルトの名無しさん2008/10/01(水) 15:40:31
ごめん。?- 行置換('foo.txt',G,A,B,member([G,B],[[2,aaaa],[4,uuuu]])).
でした。
0101デフォルトの名無しさん2008/10/02(木) 06:46:40
>>98
それだと一つの行にメイショウサムソンが2ヶ所以上あると、
その分だけコメントの付いた同じ行が出力されそう。
sub_atom/5は非決定性だから。

0102デフォルトの名無しさん2008/10/02(木) 07:09:33
それから、このような処理には一行中複数箇所を一体に置換する述語が必要だと
思う。決定性の。例えばreplaceall/4
replaceall(Atom,S1,S2,X) :-
  sub_atom(Atom,0,Len,0,Atom),
  replaceall(Atom,0,S1,S2,Y),
  concat_atom(Y,X).

replaceall(Atom,St,S1,S2,[S0,S2|R]) :-
  sub_atom(Atom,St2,Len,Rest2,S1),
  Len2 is St2-St,
  sub_atom(Atom,St,Len2,_,S0),
  St3 is St2 + Len,
  sub_atom(Atom,St3,Rest2,Rest3,Atom2),
  replaceall(Atom2,0,S1,S2,R),!.
replaceall(Atom,St,S1,S2,[Atom]).
0103デフォルトの名無しさん2008/10/02(木) 09:23:09
>>102
強引にsub_atom/5で処理している感じで重いんじゃない。
普通はatom_chars/2で一旦リストにして処理するでしょう。
最後にatom_chars/2を逆方向に使ってアトムを生成することになるけど。
0104デフォルトの名無しさん2008/10/02(木) 09:39:45
>>102
ひとつも適合する文字列がない場合はfailさせる仕様だと、replaceall/4を
replaceall(Atom,S1,S2,X) :-
  not(sub_atom(Atom,_,_,_,S1)),
  !,
  fail.
replaceall(Atom,S1,S2,X) :-
  sub_atom(Atom,0,Len,0,Atom),
  replaceall(Atom,0,S1,S2,Y),
  concat_atom(Y,X).

とすればいいのかな。
0105デフォルトの名無しさん2008/10/02(木) 11:43:08
replaceall(_置換候補述語名,Atom,X) :-
  decompcons(Atom,Chars),
  replaceall_1(_置換候補述語名,Chars,Y),
  concat_atom(Y,X).
replaceall_1(_,[],[]) :- !.
replaceall_1(_置換候補述語名,Chars,X) :-
  functor(Q,_置換候補述語名,3),
  arg(1,Q,Chars),
  arg(2,Q,CharsR),
  arg(3,Q,CharsS),
  call(Q),!,
  replaceall_1(_置換候補述語名,CharsR,Y),
  append(CharsS,Y,X).
replaceall_1(_置換候補述語名,[A|R1],[A|R2]) :-
  replaceall_1(_置換候補述語名,R1,R2).
遅いけれどこれは便利。以下のように定義(consult)する。mysという名前は任意。
mys([な,ら,び|R],R,[リ,ス,ト]).
mys([l,i,s,t|R],R,[小,文,字,で,l,i,s,t]).

?- replaceall(mys,ならびとかlistと書いてある,X).
X = 'リストとか小文字でlistと書いてある'
0106デフォルトの名無しさん2008/10/02(木) 13:54:27
mys/3のRがあるとその後方參照付きの条件設定ができる。

mys([な,ら,び|R],R,[リ,ス,ト]) :-
length(R,7). /* この置換の後は7文字 */
mys([l,i,s,t|R],R,[小,文,字,で,l,i,s,t]) :-
append(_,['\n','\n'|R2],R),
length(R,Length),
Length > 0. /* これより後に連続改行がありしかもその後に文字が続く*/

こうなってくるとPrologの独壇場。平易に並べていくらでも条件を追加できる。
0107デフォルトの名無しさん2008/10/02(木) 13:59:24
インデントしなかったから書き直し。

mys([な,ら,び|R],R,[リ,ス,ト]) :-
  length(R,7). /* この置換の後は7文字 */
mys([l,i,s,t|R],R,[小,文,字,で,l,i,s,t]) :-
  append(_,['\n','\n'|R2],R),
  length(R,Length),
  Length > 0. /* これより後に連続改行がありしかもその後に文字が続く*/
0108デフォルトの名無しさん2008/10/02(木) 20:56:12
置換が一ヶ所でしか起こらないなら、
置換(List,ListS1,LIstS2,X) :-
  append(ListS1,R,List1),
  append(ListS2,R,List2),
  append(List0,List1,List),
  append(List0,List2,X).
でよいのだが。
0109デフォルトの名無しさん2008/10/03(金) 05:29:23
>>105
replaceall/1の中にでてくる任意述語名だが、3引数の所を
4引数にして
   ......
  functor(Q,_置換候補述語名,4),
  arg(1,Q,Chars),
  arg(2,Q,CharsR),
  arg(3,Q,CharsS0),
  arg(4,Q,CharsS),
  ....
とするべきだろう。mys/3はmys/4となり、置換対象文字列のリストが
第三引数にくる。履歴などを残すためにこのような情報が必要になることがある。

mys([な,ら,び|R],R,[な,ら,び],[リ,ス,ト]).
....
0110デフォルトの名無しさん2008/10/03(金) 10:12:25
>>107 にもあるようにリストの残り要素Rを使って後方參照はできる。
場合によっては、前方も參照したい場合もあるだろう。
その場合は2引数を追加して、appendを使って、
mys([な,ら,び|R],R,_前方參照用リスト,_前方參照返しリスト,[リ,ス,ト]) :-
  append(_前方參照用リスト,[な,ら,び]_前方參照返しリスト).

リストに追加するのが[な,ら,び]であるか[リ,ス,ト]であるか微妙だが。
>>109 はさらに拡張されて、
   ......
  functor(Q,_置換候補述語名,6),
  arg(1,Q,Chars),
  arg(2,Q,CharsR),
  arg(3,Q,_前方參照用リスト),
  arg(4,Q,_前方參照返しリスト),
  arg(5,Q,CharsS0),
  arg(6,Q,CharsS),
  ....
となるだろう。
01111102008/10/03(金) 10:15:58
_前方參照返しリストの前のカンマが落ちてしまった。
mys([な,ら,び|R],R,_前方參照用リスト,_前方參照返しリスト,[リ,ス,ト]) :-
  append(_前方參照用リスト,[な,ら,び],_前方參照返しリスト).
0112デフォルトの名無しさん2008/10/04(土) 02:29:48
sed "10,20s/^/# /"
awk 'NR==10,NR==20{print "#",$0}'
0113デフォルトの名無しさん2008/10/28(火) 06:20:07
ここはPrologの隠れスレなんだね。
これだけPrologの文字列処理について書いてあるサイトは見たことが無い。
文脈自由文法的なルールによる置換などの例をぜひ載せて欲しい。
0114デフォルトの名無しさん2008/10/30(木) 13:21:44
なんか見ててもPrologが「文字列処理に向いてる」とは思えないなあ。
シンボルの処理はできると思うが、文字列処理ならawkとかPerlとかRubyとかみたいなのが楽じゃね。
0115デフォルトの名無しさん2008/11/02(日) 05:08:30
Prologについては、
最適は無理があるね。底知れず強力だとは思うけど。
■ このスレッドは過去ログ倉庫に格納されています