携帯が壊れた&もう直ったらしい。
愛用の812SHが壊れた。原因は子供に持たせてたら、がっつりしゃぶるわ、投げつけられるわ、色々あったかららしい。
お店に持っていったら、3Gカード(?)がショックでずれたりすると、不調になるとのこと。
3Gカードを一回はずして、やわらかい布で拭いた後、元に戻すと直ったりするらしい。
らしいって書いたのは、僕のはそれで直らなかったからだったりします。
で、工場行き〜。
子供がしゃぶったってことになると、ヘタすると水没扱いになって、多額な修理代を請求される恐れもありとのこと。ちなみに水没の原因の半分は子供のおしゃぶりなんだそうな。
なんのからくりか分からんのだが、水没扱いの修理代は14,700円。が、しかし、SKIカード(クレジット; 入会金、年会費無料)を作って、ソフトバンクの利用料をここから落とすと、水没時の修理代から12,000円引きになるという。
う〜ん。なんかはめられているような。。
クレジットカード勧誘のバイトでその道に詳しいうちの奥さんが「銀行口座の登録をやらないでおけば、勝手にキャンセルになるよ。」と悪魔のささやき。これに従って、とりあえず申し込みはしたものの、口座の書類は保留してある。
土曜日に修理に出して、今日もう直ったとの連絡がきた。この直りの早さは水没じゃなかったってことなのか?それともあきらめて丸ごと替えたから早かったのか?不明。
3週間かかるって言ったのに。
実は、奥さんが昔使ってて不満たらたらだった、803Tに3Gカード移し変えて使っていたんですが、あっという間に用済みかも。E*Tradeのサイト見られなくて不便だったんだよね。これが。いやいや、見ない方が平和だったとの見方もあるけど。
そんなわけで、多分明日には812SHが戻ってくる予定。
テキストファイルを読み込む
プログラミングC# p544
ファイル読み込みみたいな、プログラミング言語としての基本機能が、大分後になって書かれています。が、ちょっと都合で先取り。
using System; using System.IO; class ReadFileTest { static void Main(string[] args) { FileInfo file = new FileInfo("header.txt"); using(StreamReader sr = file.OpenText()) { string text; while((text = sr.ReadLine()) != null) { Console.WriteLine(text); } } } }
Javaでtry〜catch〜finallyを書くよりは、using文を使うことですっきりしてます。
そういやusingキーワードは、二つの意味を持つなぁ。これ、C#のポリシに反しないのかな?
ところで、結果はこう。
HTTP/1.1 200 OK Date: Tue, 12 Feb 2008 14:58:27 GMT Server: Apache Content-Type: text/html; charset=euc-jp Vary: Accept-Encoding Connection: close
これ、d.hatena.ne.jpにHEADコマンドを投げた結果だったりします。詳細は次のエントリ。
このテキストファイルを使って、正規表現の辺りを読み進めようと画策中。。
WebサーバにHEADコマンドを投げてみる
telnet www.hoge.ne.jp 80
と打ってみる。
すると、
接続中: www.hoge.ne.jp...
のように出て、接続されると画面がクリアされる。
ここですかさず
HEAD / HTTP/1.0
のように打つと、
HTTP/1.1 200 OK Date: Tue, 12 Feb 2008 15:20:12 GMT Server: Apache Content-Type: text/html; charset=euc-jp Vary: Accept-Encoding Connection: close ホストとの接続が切断されました。
のような結果が得られる。というわけです。
文字列の分割
プログラミングC# p248
String#Splitを使って、HTTPヘッダをフィールド名と値に分けます。
using System; using System.IO; class ReadHeader { static void Main(string[] args) { FileInfo file = new FileInfo("header.txt"); using(StreamReader sr = file.OpenText()) { // 最初の一行はステータス行のため読み飛ばし sr.ReadLine(); string text; while((text = sr.ReadLine()) != null) { char[] splitChars = {':'}; string[] headerValue = text.Split(splitChars); Console.WriteLine("HeaderName = {0} / Value = {1}", headerValue[0], headerValue[1]); } } } }
結果はこう。
HeaderName = Date / Value = Tue, 12 Feb 2008 14 HeaderName = Server / Value = Apache HeaderName = Content-Type / Value = text/html; charset=euc-jp HeaderName = Vary / Value = Accept-Encoding HeaderName = Connection / Value = close
意図せず、時間(14:58:27)がSplitされてしまっている。
これをうまくいくよう、わざわざ正規表現を使ってやってみる。
using System; using System.IO; using System.Text; using System.Text.RegularExpressions; class ReadHeader { static void Main(string[] args) { FileInfo file = new FileInfo("header.txt"); using(StreamReader sr = file.OpenText()) { // 最初の一行はステータス行のため読み飛ばし sr.ReadLine(); Regex theReg = new Regex("^([^:]+): (.*)$"); string text; while((text = sr.ReadLine()) != null) { MatchCollection theMatches = theReg.Matches(text ); foreach(Match theMatch in theMatches) { Console.WriteLine("HeaderName = {0} / Va lue = {1}", theMatch.Groups[1].Value, theMatch.Groups[2].Value); } } } } }
行頭からコロンじゃない文字が1つ以上続き、コロンとスペースが現れた後、任意の文字が行末まで続くという正規表現を定義してみた。
結果はこう。
HeaderName = Date / Value = Tue, 12 Feb 2008 14:58:27 GMT HeaderName = Server / Value = Apache HeaderName = Content-Type / Value = text/html; charset=euc-jp HeaderName = Vary / Value = Accept-Encoding HeaderName = Connection / Value = close
時間も正しく表示できた。
import java.io.*; import java.util.regex.*; class ReadHeaderRegex { public static void main(String[] args) throws Exception { BufferedReader br = null; try { br = new BufferedReader(new FileReader("header.txt")); // 最初の一行はステータス行のため読み飛ばし br.readLine(); Pattern p = Pattern.compile("^([^:]+): (.*)$"); String text = null; while((text = br.readLine()) != null) { Matcher m = p.matcher(text); if(m.matches()) { System.out.printf("HeaderName = %s / Val ue = %s\n", m.group(1), m.group(2)); } } } finally { if(br != null) { br.close(); } } } }
正規表現の書き方自体はもちろん同じ。結果ももちろん同じ。
theReg = Regexp.new("^([^:]+): (.*)$"); open("header.txt") { |file| # 最初の一行はステータス行のため読み飛ばし file.gets while text = file.gets do matchData = theReg.match(text) puts "HeaderName = #{matchData[1]} / Value = #{matchData[2]}" end }
すっきり!(^o^)
くどいようだが、正規表現の書き方自体はもちろん同じ。結果ももちろん同じ。
Set fs = CreateObject("Scripting.FileSystemObject") Set ts = fs.OpenTextFile("header.txt") Set theReg = New Regexp theReg.Pattern = "^([^:]+): (.*)$" ' 最初の一行はステータス行のため読み飛ばし ts.ReadLine() While ts.AtEndOfStream = False lineData = ts.ReadLine() Set matches = theReg.Execute(lineData) WScript.Echo "HeaderName = " & matches(0).submatches(0) & " / Value = " & matches(0).submatches(1) Wend ts.Close()
var fs = new ActiveXObject("Scripting.FileSystemObject"); var ts = fs.OpenTextFile("header.txt"); var theReg = /^([^:]+): (.*)$/; // 最初の一行はステータス行のため読み飛ばし ts.ReadLine(); while(!ts.AtEndOfStream) { lineData = ts.ReadLine(); var matches = theReg.exec(lineData); WScript.Echo("HeaderName = " + RegExp.$1 + " / Value = " + RegExp.$2); } ts.Close();
open(FILE, "header.txt"); # Skip Status Line while(<FILE>) { chomp; if($_ =~ /^([^:]+): (.*)$/) { print "Header = $1 / Data = $2\n"; } } close(FILE);
perl版が一番手になじんだ気がした。
それにしても、カッコでくくって後から使う機能は「後方参照」とか呼ぶみたいですけど、awkとかじゃ使えないんですね。意外。