• ベストアンサー

特定の文字の個数を取得する簡単な方法ありますか?

タイトルの通りなのですが、1行中の特定の文字の個数を取得し、ある個数の時だけその行を表示させようとしています。例えば特定の文字を":"とし、":"がちょうど5個ある行だけ表示させる場合、splitを使って以下のようなコードを考えましたが、どうもスマートじゃない気がします。しかもこれだと"a:b:c:d:e:"のように、行末が":"になっている場合は、$num=5となってしまい、正しく動作しません。どなたか解決策をお願いいたします。 while(<IN>){ @list = split( /:/ , $_ ); $num = @list; if( $num == 6 ){ print "$_\n"; } }

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

  • ベストアンサー
  • tthe_mine
  • ベストアンサー率46% (19/41)
回答No.1

@tmp = ($_ =~ m/:/); if (scalar(@tmp) == 6) でどうでしょう。

すると、全ての回答が全文表示されます。

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

#5 のように, tr を使うのが普通だと思います. ・tr は「変換した文字の個数」を返す ・tr で後ろが空の場合は前と同じものを指定したとみなす (つまり実質的に変換しない) ですから. あ, 今は「: が 5個」だから tr/:// == 5 です.

すると、全ての回答が全文表示されます。
  • okiyoshi
  • ベストアンサー率34% (11/32)
回答No.5

# No.4さんのバリエーションですが・・ while(<IN>){ print if tr/:// == 6; }

すると、全ての回答が全文表示されます。
  • rafysta
  • ベストアンサー率45% (24/53)
回答No.4

while(<>){ print if(scalar(my @tmp = m/:/g) == 5); }

すると、全ての回答が全文表示されます。
  • leap_day
  • ベストアンサー率60% (338/561)
回答No.3

こんにちは name.cgi(データファイル)に以下のようにデータが入ってるとして a:b a:b: a:b:c:d: a:b:c:d:e a:b:c:d:e: a:b:c:d:e:f こんな風にしてみました open(IN,"./name.cgi"); @log=<IN>; close(IN); # データ数取得 @n=split(/\n/,@log); $n=@n; foreach(@log) { for(1..$n){ # 行末に『:』があるか調べる $word="$log[$j]"; if($word !~ /:$/) { # 行末に『:』がないもので『:』の個数を調べる @num=split(/:/,"$log[$j]"); $num=@num; # 書き出し処理 if($num eq "5"){ print "一致するもの:$log[$j]<br>\n"; }else{ print "一致したけど:$log[$j]<br>\n"; } }else{ print "一致しないもの:$log[$j]<br>\n"; } $j++; } } 表示結果は 一致したけど:a:b 一致しないもの:a:b: 一致しないもの:a:b:c:d: 一致するもの:a:b:c:d:e 一致しないもの:a:b:c:d:e: 一致したけど:a:b:c:d:e:f となって『a:b:c:d:e』だけ取得できました(^^)

すると、全ての回答が全文表示されます。
  • guci-ok
  • ベストアンサー率33% (49/146)
回答No.2

タイトルの通り? 取得したいのは、特定の文字ではなく、 特定の文字で区切られたデータではないですか。 簡単な方法かどうか、正規表現で思うとおり指定するのはどうです。 D:\>C2.pl NG: 1:2:3:4:5: OK: 1:2:3:4:5:6 #!Perl use strict; for ('1:2:3:4:5:', '1:2:3:4:5:6') {  if (m|^([^:]+:){5}[^:]+$|) {   print "OK: $_\n";  } else {   print "NG: $_\n";  } } __END__

すると、全ての回答が全文表示されます。

関連するQ&A