• ベストアンサー

1文字ごとに<br>タグを挿入するルーチンを見てください。

文字列があって、1文字1文字の後ろに<br>タグを挿入して、たてに表示させたいと思います。 一応このようなサブルーチンを考えました。 sub insertChar{ local $string = $_[0]; local $char = $_[1]; local $new = ''; local @chars = (); local $temp = ''; while($string =~ s/^.//){ ###全角の1バイトめがtempに入っていたら。2バイトめと一緒に配列に入れる。 if ($temp) {$temp .= "$&"; push (@chars, $temp); $temp = '';next;} ###tempが空のばあい、半角文字じゃないかどうかをチェック。半角文字で無ければtemp変数に取っておく。 if ($& =~ /[^a-zA-Z0-9_?,.!@\\\/\~\*\&\^\%\$\#\-\+\s\(\)\[\]\"\'\{\}\<\>\:\;\`\|]/) {$temp = "$&"; next;} ###tempが空で、全角の1バイトめでもなかったら半角文字ということで、素直に配列に入れる。 push (@chars, "$&"); } $new = join ("$char", @chars);return $new; } これを $hoge = &insertChar("$hoge",'<br>'); 見たいな感じで使っています。実際期待通りに動いてはいるんですが、なんかきっともっとスマートなやり方があると思うんです。 とくに、半角文字を判断させるところはとにかく思い付く限りの半角もじをリストアップさせているだけで、しかも、どれをエスケープすべきかわからないので全部エスケープさせてしまいました。 一応どういうロジックで処理しているか説明しますと、受け取った文字列を1バイトづつ判断し、それが半角英数記号文字だったら@chars配列へ格納し、半角英数記号文字以外は2バイト文字の1バイトと目判断して$tempに格納、次の2バイトめと一緒にして、@charに格納。最後にjoinです。 なんか、もっと優雅な方法ってないものでしょうか? よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • tfp
  • ベストアンサー率37% (3/8)
回答No.2

こんにちは。 まず、文字の正規表現に関しては大崎さんのPerlメモがとても参考になります。 http://www.din.or.jp/~ohzaki/perl.htm で、私ならこう書くというのを一つ。 sub insertChar { my ($str, $char) = @_; my $h_sjis = '(?:[\x00-\x7F\xA1-\xDF])'; my $z_sjis = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; my @str = $str =~ /($h_sjis|$z_sjis)/og; return join($char, @str); } 上記はShift_JIS用に書いたコードですが、正規表現部分を変えることで、他の文字コードでも使えると思います。

nak205
質問者

お礼

これはすごいです!!! 早速sjisでやってみました。 いただいたURLでEUCも分かると思います。 配列へ入れる方法もこんな方法があるなんて知りませんでした。 どうも有り難うございました。

その他の回答 (1)

  • sueoka
  • ベストアンサー率38% (24/62)
回答No.1

こんばんわ。 Perlはやったことないので、処理の部分は良く分からないんですが、 全角文字かどうかの判断は、C言語の場合は 「そのバイトのコードが0x80以上だったら全角」 と判定していたかと思います。 (0x80以上だったら次のバイトと合わせて全角文字になるということ) で、今家にあったCGI&Perlと言う名の本を引っ張り出して 眺めてみたところ、Perlでは「ord」と言うのを使えば良さそうです。 これで判定対象の文字列を16進数のコードに変換して、 これが0x80以上であれば全角文字の1バイト目である・・・と。 これ以上は良く分かりません。すんません(笑

nak205
質問者

お礼

早速ありがとうございます。 Perlのパターンマッチに捕われ過ぎていたせいか、文字コードのXXXX以上はなんちゃらという発想がぜんぜん浮かんできませんでした。 いまEUCでやってるんですけど、それだと0x80ではなく他のコードになるんでしょうね。

関連するQ&A