読者です 読者をやめる 読者になる 読者になる

高見知英のかいはつにっし(β)

高見知英のアプリケーション開発日誌 のほか、地域活動などの活動報告ブログ。

正規表現に苦戦

プログラミング

今日はおんぷ村用の文字列展開用のコードを書いていました。
文字列展開というのは、このはてなのはてな記法のような、HTMLの代わりになる表記法のことで、わたしは以前からはてな記法ににた記法を正規表現で書いて使っています。これは全部正規表現なので可読性は低く、この際Text::Hatenaにでも変えてしまおうかと思いましたが、結局今の記法を修正して利用することに。
だってText::Hatena、たくさんモジュールを使って、レンタルサーバへの配置が面倒そうな割にはValidなHTMLを作らないので、メリットが少ないんですもの。モジュールのソースコードを見ると、なにやらわたしの知らない書き方でどこをどういじればよくわからなかったし、モジュールの処理後にこちらでいろいろ手を加えるのは不安ですし。
――というわけで、以前作った正規表現をコピーしてきて、整理しながらいろいろやってました。もともとpタグの挿入など、ちょこちょこ問題もあったので、その処理が結構手間取りましたね。正規表現べた書きのままではあまりにも不便なので、ハッシュリストにパラメータを格納 なんてことまでやってしまいました。

  push(@regs, { find => '((?:(?<=\n)\++.*\n)+)',
                replace => '$_=$1; s|^\+(.+)$|<li>$1</li>|mg; "<ol>\n$_</ol>\n"', 
                option => 'ge',}); # olで囲む

こんな感じで、findを検索文字列、replaceを置き換え後文字列、optionをオプションとして後で一斉に正規表現をかける と言うしくみ。

  foreach my $r(@regs)
  {
    eval("\$text =~ s\@$r->{find}\@$r->{replace}\@$r->{option}");
    if($@){ die "\$text =~ s\@$r->{find}\@$r->{replace}\@$r->{option}\n\t$@"; }
  }

実行コードは上のような感じ。evalの使い方がなかなかわからなくて、結構大変でした。変数展開の順序を意識しながらとなると、結構evalを使いこなすのは難しいかも・・・。
結果、ひとまず動くところまでは行きましたし、無事w3cのバリデータにもValidと言われるところまでできました。相変わらずきれいとは言えないコードですが、おんぷ村の公開後にぼちぼちきれいにしていって、終わったら公開でもしましょうかね。


――それにしても、CGIで出力されるHTMLというのはなんと汚いことか。汚いというか、インデントも行間もぐちゃぐちゃで、読めたものではありません。まあ、空行までは容易に修復できますが、インデントはねえ――。さっきHTML::TreeBuilderと言うものを使っては見たものの、あれはあれで使うとInValidなHTMLを生成することがあるみたいだし。
XHTMLだしXML::TreePPで何とかならないかな と思ったものの、やっぱりだめ。XMLのコードまでは再現しますが、タグの並び順までは共通じゃないんでしたね・・・。
まあ、見るぶんには影響はないものの、何か方法はないんでしょうか。このままじゃやはり気持ち悪いので。


ひとまず当初予定していた建造物はほとんど完成。今週中には何とかできそうです。
ほんとうは1月8日のおんぷ村誕生日にあわせたかったですが、クリエイティブチームの準備もあるし、今回はここまでですかね。また今度、空いてる時間に少しずつ完成を目指してみましょう。