$text = "abcdefg";

という風に、$textに入った文字列が半角の場合、

頭から3文字を抜き出すのは、

$text = substr( $text, 0, 3 );

とすれば問題が無い。
($text には、「abc」が入っている)

しかし、

$text = "あいうえお";

のように全角あるいは、半角と全角が混在する場合に問題が生じる。

詳しくは、

http://www110.kir.jp/study/jissen/script999003.html

を参照下さい。

では、全角が入った場合はどうすれば良いか?

それについては

http://www.favorite-labo.org/archives/315.html

が詳しい。

上記のページの通りにすると、全角は2バイト・半角は1バイトとカウントする。
そして、(trimの2つ目の変数)×2の数より小さく、最大のバイト数を表示する
というロジックになっている。

具体的には、(以下のコードはutf-8で保存)

#!/usr/bin/perl

use Jcode;

$text = "あaいbうcえdおeかfきgくhけiこ";

$text = &trim($text, 5, '...');

print "Content-type: text/html;charset=utf-8\n\n";
print<<"<!--HTML-->";
$text
<!--HTML-->

sub trim {
my($string, $width, $marker) = @_;

my $jcode_ins = new Jcode($string, 'utf8');
$jcode_ins->jfold($width * 2);
$string = $jcode_ins->utf8;

if ($string =~ /\n/) {
$string = (split(/\n/, $string))[0] . $marker;
}

return $string;
}

とすれば一応動き、
あaいbうc...
と表示される。

phpには、mb_strimwidth という関数がある分、perlが不便に感じた。