• ベストアンサー

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です。 なんか、もっと優雅な方法ってないものでしょうか? よろしくお願いします。

  • Perl
  • 回答数2
  • ありがとう数3

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

  • ベストアンサー
  • 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

  • 文字列をハッシュにしなければならないのですが

    C言語にさ ファイルの中にある、3バイトunicodeの漢字文字列郡をハッシュテーブルに格納してハッシュを作りたいんですが、取っ掛かりすらつかない状況です。 とりあえず、配列から3バイトの16進数にして、後はその文字列分の16進数を足して、それを割ってキーをつくりテーブルにいれる、としようとしています。 配列から3バイトの16進数にする int joint(char a, char b, char c){ int join = 0; join = a<<8; join = (0x0000FF00 & join) + (0x000000FF & b); join = join<<8; join = (0x00FFFF00 & join) + (0x000000FF & c); return join; } このように16進数にするのですが、最初の取っ掛かりとしてのハッシュについては、どうやったらハッシュテーブルに格納でくるのかいまいちわからないのです。誰かわかりやすく教えてください。

  • 配列への文字列の追加ってどうやって追加するの?

    配列に文字列をいれたいのですが char a[100]; sprintf(a,"AB"); と書くと a[0]にAが a[1]にBが a[2]に\0が格納されますよね。 「配列に一度格納された文字列に新たな文字列を追加」したいのです。 つまり この\0を上書きしてa[2]から CD を追加し、結果 a[0]にAが a[1]にBが a[2]にCが a[3]にDが a[4]に\0が 格納されているようにしたいのです。 半角英数だったらできるのですが全角だとどうやるのでしょうか。 やりたい事は以下のようなものです。 "あい"を1度目の処理で配列に文字列を格納し、次の処理で"うえ"を追加し、 配列aをprintfするとき「あいうえ」が出力されるようにしたいのです。 どなたか教えてください(>_<

  • 文字のバイトサイズの取得

    25バイト以上ある文字配列を25バイトまでに切り取りたいのです。 全て半角英数ならstr.substring(0 ,25)ですみますが 日本語も入っているのでsubstringが使えません。 そこで,バイト配列を使おうと思ったのですがうまくいきません。どうかお願いします。 例) String E = "AAAAAAAAAAAAAあああああああ"; byte S[] = new byte[100]; S=E.getBytes(); ByteArrayOutputStream out = new ByteArrayOutputStream(); for(int n = 0; n < 25 ; ++n){ out.write(S[n]); } System.out.println(out.toByteArray()); 結果として"AAAAAAAAAAAAAあああ"が出力されてほしい

    • ベストアンサー
    • Java
  • C++ vector中のnewしたの文字列の削除の問題

    C++の新人ですが、困っている質問をさせていただきます。 C++のvectorの中にchar型の文字列を格納していて、どうやって、 memory leak が発生しないようにクリアしますか? たとえば、以下の例 std::vector<char *> vc; void pushvc(); int main(){ pushvc(); } void pushvc(){ char* a = new char[10]; char* b = new char[10]; a="sss"; b="bbb"; vc.push_back(a); vc.push_back(b); } よろしくお願いします。

  • 【VB6】文字判定

    変数xに半角英数記号1文字が格納されています。 格納されている文字が数字か大英字か小英字か記号かを判定するにはどうすればいいでしょうか? 宜しくお願いします。

  • new演算子

    1:new演算子は2次元配列はつくれますか?? 2:new演算子で配列を動的に生成して以下の文字を代  入したい場合はどうすればいいですか?    char* a = new char[3]; a[] = {"ABC" "EFG" "HIJ"}    上のプログラムだと、a[0]にABCの文字が入りませ  ん。どうすれば、a[0]にABCを格納できますか?

  • タグ混じりの文字列を、タグの前後で分割して配列に格納したい

    Flash8使用です。 XMLファイルから読み込んだ、タグ混じりの文字列を、 タグの前後で分割して、配列に格納したいと考えています。 <a>我が輩は<b kana="ねこ">猫</b>である。</a> という文字列を、 <a>,我が輩は,<b kana="ねこ">,猫,</b>,である,</a> という配列にしたいのです。 最初の文字列(変数lineに代入)をsplitを使って「<」で分割し、 次に生成された配列の要素をに、1つずつ消された「<」を補うということをして、 ,<a>我が輩は,<b kana="ねこ">猫,</b>である,</a> という配列は作れました。 しかしここからさらに「>」で分割する方法がわかりません。 どのような方法がありますでしょうか。 特にsplitを使う方法にこだわっているわけではないので、 最初からまったく異なる方法でももちろん大歓迎です。 よろしくお願いします。 以下、現在のコードです。 var temp:Array = line.split("<"); for ( var n = 1; n<temp.length; n++) { temp[n] = "<" + temp[n]; }

    • ベストアンサー
    • Flash
  • C言語の文字列について

    C言語で文字列のヌルについて、理解があいまいな点があり、教えて欲しいのですが、以下のようにsprintfで書式し代入した際に最後は0(ヌル文字)をセットしてくれるのでしょうか?4バイト目の文字が何か知りたいです。 char temp[100];時では0で初期化されていることは保障されていませんが、大抵は0で埋まっていますが、sprintfの仕様が知りたいです。 char temp[100]; sprintf(temp, "test");とした時に 01234バイト目 test?????????????.... 話は変わりますが、以下のようにするとエラーになりましたが、 特定の位置の値をセットする方法はどのようなものがあるのでしょうか? temp[10] = (temp[10] == '0') ? (char)'1' : (char)'0';

  • 全角日本語について

     全角日本語はchar型を2つ連続で続けて出力しないといけませんよね。半角だと1バイトですむところを2バイト使っているわけですけど。半角と全角が入り混じったテキストから的確に1文字ずつ取り出すことは出来ないのでしょうか?(2バイトずつ取り出すと、半角のところで文字化けになってしまいますし、1バイトずつだと全角のところが文字ばけしますよね。)半角の時は、半角を、全角の時は全角をという風に。。。  あと、全角の日本語を一文字として扱う型は何かないでしょうか。いつも、charの配列でchar[0],char[1]として使っているのですが。 ちなみに、windows98でBorlandのTurbo C++を使って、C言語で書いています。 なにとぞ、よろしくおねがいします。

  • C言語で全角文字の扱いについて

    全角を配列に格納するには2バイトを使いますよね。そこで気になることがあるのですが、以下のプログラムで一文字目(私)を表示するには、どうしたらいいのですか?これは間違っています。 教えて下さい。 #include <stdio.h> main(){ char array[100]={"私の名前はXXXです"}; printf("%s",array[0]); }

専門家に質問してみよう