Posted by lawrhino - 2007.07.26,Thu
技術系の内容は はてな で
書く事にしました。
はてなに記事を書いた時はこっちにリンクだけ貼るつもり。
なんでかっていうとこっちはもっと軽く、
そしてゆるく使った方が良さげかなって思ったので。
あとこれが一番大きいんだけど検索がないこと。
まぁこれからも思い立った時につらつらと
書きたいと思います。
書く事にしました。
はてなに記事を書いた時はこっちにリンクだけ貼るつもり。
なんでかっていうとこっちはもっと軽く、
そしてゆるく使った方が良さげかなって思ったので。
あとこれが一番大きいんだけど検索がないこと。
まぁこれからも思い立った時につらつらと
書きたいと思います。
PR
Posted by lawrhino - 2007.07.19,Thu
MSのCSV形式をプログラムから扱う為の
モジュールを作成する事になった。
使用言語はJAVA。
まず出力されるCSVの仕様の定義から
・全てのデータは,(カンマ)区切り。
・文字列データは"(ダブルクォート)で囲まれている。
・文字列中の"は""としてダブルクォート2回でエスケープする
・文字列データ中には,、"、改行コード(
)が含まれる。
処理の肝となる部分は
・文字列中の改行コードの処理
・文字列中のカンマの処理
の2点だろう。
とりあえず単純にそれら特殊文字を考慮に入れずに
1行分のカンマ区切りデータを読み込む処理を作成。
ファイルの読み込みにはBufferedReaderクラスを使う。
次に文字列データ中に含まれる改行コードを考慮に入れた処理を追加する。
判断方法はまず文字列中にある連続したWクォート(エスケープされているので連続している)
をreplaceAll(""""","")を使って全て消す。
空文字列の場合も連続しているが一緒に消しても問題はない。
すると残りは文字列を囲む前後のWクォートだけとなるので、
列ごとに必ず2個ずつ存在することになる。
途中で改行が含まれてる列があればその列は前の1個だけとなるので、
読み込んだ行全体としてはWクォートの数が奇数になる。
その場合は続けて次の行を読み込む。
これを繰り返し偶数になるところまで読み込む事で1レコード分を
読み込める。
主要部分だけを書くと以下のようなイメージ
残るはカンマの処理だがこれも同様の方法で判定できる。
とりあえず改行判定で取得できた1レコード分の文字列を
splitを使いカンマで分割する。
次に分割されたトークン配列の先頭から順番にチェックしていき、
Wクォートが含まれた場合は文字列型データ列とみなす。
文字列型データ列の場合は、改行判定と同じ方法で
Wクォートの数が偶数かどうかで判定。
奇数の場合は途中にカンマが含まれていたと考えられるので
次のトークンと文字列結合を行う。
(この際、カンマを追加する必要がある)
結合された文字列に対して再度チェックを行い奇数であれば
さらに次のトークンと結合。
以下これを繰り返すことで一つの文字列に復元ができる。
実際のコードは以下のような感じ。
あとはこれらを使いやすいようクラス設計をする事で完成。
ただカンマ分割部分は正規表現を上手く使う事でもっとシンプルにできるだろう。
・Wクォートで囲まれたカンマを除く、カンマ
という正規表現が書けたらおそらく一発で分割できる。
ただ正規表現は不勉強ですぐには思い浮かばなかった為、
今回は力技でやってみた。
わかる人いたら是非ご教授ください。
モジュールを作成する事になった。
使用言語はJAVA。
まず出力されるCSVの仕様の定義から
・全てのデータは,(カンマ)区切り。
・文字列データは"(ダブルクォート)で囲まれている。
・文字列中の"は""としてダブルクォート2回でエスケープする
・文字列データ中には,、"、改行コード(
)が含まれる。
処理の肝となる部分は
・文字列中の改行コードの処理
・文字列中のカンマの処理
の2点だろう。
とりあえず単純にそれら特殊文字を考慮に入れずに
1行分のカンマ区切りデータを読み込む処理を作成。
ファイルの読み込みにはBufferedReaderクラスを使う。
BufferedReader br = new BufferedReader();
String line = br.readLine();
String[] cols = line.split(",");
for (int i = 0; i < cols.length; i++)
cols[i] = cols[i].replaceFirst("^"","").replaceFirst(""$","");
次に文字列データ中に含まれる改行コードを考慮に入れた処理を追加する。
判断方法はまず文字列中にある連続したWクォート(エスケープされているので連続している)
をreplaceAll(""""","")を使って全て消す。
空文字列の場合も連続しているが一緒に消しても問題はない。
すると残りは文字列を囲む前後のWクォートだけとなるので、
列ごとに必ず2個ずつ存在することになる。
途中で改行が含まれてる列があればその列は前の1個だけとなるので、
読み込んだ行全体としてはWクォートの数が奇数になる。
その場合は続けて次の行を読み込む。
これを繰り返し偶数になるところまで読み込む事で1レコード分を
読み込める。
主要部分だけを書くと以下のようなイメージ
String line = br.readLine();
while(countChar(replaceAll("""""",""),'"',0) % 2 == 1){
line += "
" + br.readLine();
}
// 文字列中の特定文字をカウントする関数
private int countChar(String str, char c, int start) {
int i = 0, index = str.indexOf(c, start);
return index == -1 ? i : countChar(str, c, index + 1) + 1;
}
残るはカンマの処理だがこれも同様の方法で判定できる。
とりあえず改行判定で取得できた1レコード分の文字列を
splitを使いカンマで分割する。
次に分割されたトークン配列の先頭から順番にチェックしていき、
Wクォートが含まれた場合は文字列型データ列とみなす。
文字列型データ列の場合は、改行判定と同じ方法で
Wクォートの数が偶数かどうかで判定。
奇数の場合は途中にカンマが含まれていたと考えられるので
次のトークンと文字列結合を行う。
(この際、カンマを追加する必要がある)
結合された文字列に対して再度チェックを行い奇数であれば
さらに次のトークンと結合。
以下これを繰り返すことで一つの文字列に復元ができる。
実際のコードは以下のような感じ。
private String[] csvSplits(String line, String delimiter) {
LinkedList results = new LinkedList();
String[] tokens = line.split(delimiter, -1);
for (int i = 0; i < tokens.length; i++) {
if (results.isEmpty() || isCorrectElement((String)results.getLast())) {
results.add(tokens[i]);
} else {
results.add( tokens.removeLast() + delimiter + tokens[i] );
}
}
return (String[])results.toArray(new String[0]);
}
private boolean isCorrectElement(String str) {
return 1 == countChar(str, '"', 0) % 2 ;
}
あとはこれらを使いやすいようクラス設計をする事で完成。
ただカンマ分割部分は正規表現を上手く使う事でもっとシンプルにできるだろう。
・Wクォートで囲まれたカンマを除く、カンマ
という正規表現が書けたらおそらく一発で分割できる。
ただ正規表現は不勉強ですぐには思い浮かばなかった為、
今回は力技でやってみた。
わかる人いたら是非ご教授ください。
Posted by lawrhino - 2007.07.17,Tue
今日は祇園祭の山鉾運行日。
朝から和服を着た外国の方をたくさんみました。
外国の方に祇園祭の見所を説明するとしたら
なんて説明したらいいだろう?
山鉾の日本的なデザイン性?
囃子の音色?
やっぱりベタに辻回し?
ただ辻回しとかもなんて古典的なやり方だと
個人的には思うわけですよ。
日本人にとっては趣きのあるそれらも、
普段から情緒を重きを置くわけではない国の人間だったら
非合理的に感じるんじゃなかろうか。
今日が終わった時点で出勤時に見た外国人達が
祇園祭に何を考え、果たして面白いと
感じたのかどうか聞いてみたい。
朝から和服を着た外国の方をたくさんみました。
外国の方に祇園祭の見所を説明するとしたら
なんて説明したらいいだろう?
山鉾の日本的なデザイン性?
囃子の音色?
やっぱりベタに辻回し?
ただ辻回しとかもなんて古典的なやり方だと
個人的には思うわけですよ。
日本人にとっては趣きのあるそれらも、
普段から情緒を重きを置くわけではない国の人間だったら
非合理的に感じるんじゃなかろうか。
今日が終わった時点で出勤時に見た外国人達が
祇園祭に何を考え、果たして面白いと
感じたのかどうか聞いてみたい。
Posted by lawrhino - 2007.07.15,Sun
ちょうど2年ちょっと前にLinuxで構築した自宅のサーバを
再構築しようと思っているんだけど、
どのLinuxディストリビューションを使おうか。
主な用途としては
・WEB(AP)サーバ
・メールサーバ
・ファイル共有サーバ(WEBDAV)
ぐらい。
WEBサーバへの内側からのアクセスの為にDNSもいれる。
マシンのスペックは、
CPU:Celeron600Mhz
Mem:192MB
HD:20GB
前回はVineLinux2.4を利用した。
情報量の多さではFedoraを選びたいとこだけど、
動作環境を満たしていないと思われるので却下。
Debianあたりが妥当な選択なのかな。
Ubuntuとかも良く聞くけどどうなんだろう。
基本は放置プレーなんでできるだけ
手のかからないってのもポイントの一つ。
そう考えると更新頻度の低いVineを
もう一度ってのもありだよな。
まぁディストリビューションの選択云々なんかより、
現在動いているデータのスムーズな移行の方が
遙かに大変なんだけどね。。。
再構築しようと思っているんだけど、
どのLinuxディストリビューションを使おうか。
主な用途としては
・WEB(AP)サーバ
・メールサーバ
・ファイル共有サーバ(WEBDAV)
ぐらい。
WEBサーバへの内側からのアクセスの為にDNSもいれる。
マシンのスペックは、
CPU:Celeron600Mhz
Mem:192MB
HD:20GB
前回はVineLinux2.4を利用した。
情報量の多さではFedoraを選びたいとこだけど、
動作環境を満たしていないと思われるので却下。
Debianあたりが妥当な選択なのかな。
Ubuntuとかも良く聞くけどどうなんだろう。
基本は放置プレーなんでできるだけ
手のかからないってのもポイントの一つ。
そう考えると更新頻度の低いVineを
もう一度ってのもありだよな。
まぁディストリビューションの選択云々なんかより、
現在動いているデータのスムーズな移行の方が
遙かに大変なんだけどね。。。
Posted by lawrhino - 2007.07.10,Tue
一昨日、衣笠立命館大学前にある堂本印象美術館にいってきた。
建物の概観が特徴的で、美術館というよりも
豪邸といった感じだ。
壁には凹凸のある抽象的なデザインがたくさん施されている。
中に入って説明を見てから初めて知ったのだけど、
堂本印象というのは名前らしい。
堂本が姓だというはわかったが、
印象が名前だったとは思ってもいなくて、
きっと印象派の絵を描く人なんだろうと、
勝手に予想してたけど全く違いました。
実際の絵はというと、すごく気楽にスケッチしたものが多く、
ほとんどが風景画だった。
国内・国外問わずいろんなところに旅をしてた事が
伺える作品集で現地に行っては写真ではなく、
絵でその景色を残す為にその場で
一気に描きあげてたのだろうね。
ラフスケッチというレベルのものが多かったです。
そんな中にも現地の雰囲気が出てるものが数点あって
上手く特徴を捉えてるなと思うものはあったんだけど、
個人的にこれ、なんか好きだなと思えるような作品には
出会えませんでした。
現在、没後30年というイベントをやっています。
建物の概観が特徴的で、美術館というよりも
豪邸といった感じだ。
壁には凹凸のある抽象的なデザインがたくさん施されている。
中に入って説明を見てから初めて知ったのだけど、
堂本印象というのは名前らしい。
堂本が姓だというはわかったが、
印象が名前だったとは思ってもいなくて、
きっと印象派の絵を描く人なんだろうと、
勝手に予想してたけど全く違いました。
実際の絵はというと、すごく気楽にスケッチしたものが多く、
ほとんどが風景画だった。
国内・国外問わずいろんなところに旅をしてた事が
伺える作品集で現地に行っては写真ではなく、
絵でその景色を残す為にその場で
一気に描きあげてたのだろうね。
ラフスケッチというレベルのものが多かったです。
そんな中にも現地の雰囲気が出てるものが数点あって
上手く特徴を捉えてるなと思うものはあったんだけど、
個人的にこれ、なんか好きだなと思えるような作品には
出会えませんでした。
現在、没後30年というイベントをやっています。
カレンダー
プロフィール
HN:
lawrhino
性別:
非公開
最新記事
忍者アド
最新TB
アクセス解析
Template by mavericyard*
Powered by "Samurai Factory"
Powered by "Samurai Factory"
