正規表現で文字列を判定する方法とは?

このQ&Aのポイント
  • 正規表現を使用して、文字列のパターンマッチングを行う方法について教えてください。
  • 特定の文字列の分解や展開方法について教えてください。
  • 正規表現の使い方や注意点について教えてください。
回答を見る
  • ベストアンサー

以前、ご質問させていただき、ご回答をいただいたのですが、

以前、ご質問させていただき、ご回答をいただいたのですが、 'server0[123]', 'client0[1-35-7]', 'client0[13-69]', 'client[1-3][0-9]' の文字判定をお聞きし、自分なりにサブルーチン化して対応いたしましたが、 このたび 'server0[1-3]0','server0[1-3]2','client0[a-z1]',client[a-c][12] 等の文字列も判定する必要がでてきました。 sub host{ my @reg_str = @_; my (@work, @result); foreach my $reg_str (@reg_str) { if ($reg_str = ~/\[/ ){ my $head = substr($reg_str, 0, index($reg_str, '[')); my @num = map { s/(\d)-(\d)/join('', $1 .. $2)/eg; [split //] } $reg_str =~ /\[([\d-]+)\]/g; @ref_result = (); @ref_result = comb(@num); print join(',', map { $head . $_ } @result), "\n\n"; }else{ print "$reg_str\n"; } sub comb { my $ref = shift; @result = (); foreach my $i (@$ref) { push @work, $i; unless (@_) { push @result, join('', @work); } else { comb(@_); } pop @work; } return (@result); } } 'server0[123]', 'client0[1-35-7]', 'client0[13-69]' の分解は可能なのですが、 'client[1-3][0-9]' は client10,client11,client12・・・・・・client37,client38,client39 となってほしいのですが、 client31,client32・・・・・,client38,client39となってしまいます。 また括弧の後ろに括弧無しがきた場合は、うまく展開できません。 お忙しいところ、誠にくだらない質問かもしれませんが、お力をお借りできれば幸いです。 よろしくお願いします。

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

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

  • ベストアンサー
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.2

次のプログラムですべて展開できると思います。 use strict; my @reg_str = ('server0[123]', 'client0[1-35-7]', 'client0[13-69]', 'client[1-3][0-9]', 'server0[1-3]0','server0[1-3]2','client0[a-z1]', 'client[a-c][12]'); my (@work, @result); foreach my $reg_str (@reg_str) { my @list = grep { length } split /(\[[-\w]+\])/, $reg_str; foreach my $item (@list) { if ($item =~ s/\[(.*)\]/$1/) { $item =~ s/(\w)-(\w)/join('', $1 .. $2)/eg; $item = [split //, $item]; } else { $item = [$item]; } } @result = (); comb(@list); print join(',', @result), "\n\n"; } sub comb { my $ref = shift; foreach my $i (@$ref) { push @work, $i; unless (@_) { push @result, join('', @work); } else { comb(@_); } pop @work; } }

その他の回答 (1)

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

ん~, なんでそんなわけのわからんことをする必要があるの?

関連するQ&A

  • C++のstring型文字列を分割して配列に入れる

    string str = "AABBCCDD"; これを以下のように分割する方法が知りたいです。 result[0] = "AA"; result[1] = "BB"; result[2] = "CC"; result[3] = "DD"; 分割する固定長2と、結果を保存するstring型のresultを与えれば 以下のようになる関数を作りたいのですが、 C++の標準機能でスマートにできる方法がベストです。 Perlでいうunpack見たいなものです。 use strict; my $str = "AABBCCDD"; my @result = unpack '(a2)*', $str; // こんなことをC++でしたい foreach my $val (@result) { print $val, "\n"; } よろしくお願いします。

  • string型の固定長文字列を配列等に分解する方法

    先ほどジャンル違いで質問してしまったので、再度C/C++の方へ質問いたします。 string str = "AABBCCDD"; これを以下のように分割する方法が知りたいです。 result[0] = "AA"; result[1] = "BB"; result[2] = "CC"; result[3] = "DD"; 分割する固定長2と、結果を保存するstring型のresultを与えれば 以下のようになる関数を作りたいのですが、 C++の標準機能でスマートにできる方法がベストです。 Perlでいうunpack見たいなものです。 use strict; my $str = "AABBCCDD"; my @result = unpack '(a2)*', $str; // こんなことをC++でしたい foreach my $val (@result) { print $val, "\n"; } よろしくお願いします。

  • printfやsprintfで、0に符号 (+) をつけない方法

    Perlの問題ではないのかなとも思うのですが、 my @num1 = (1, 0, 2, 0); my @num2 = (0, -3, 0, 2); foreach my $num1 (@num1) { my $num2 = shift @num2; printf "%+d%+d\n", $num1, $num2; } などと%+dとすると、0の場合に+0となってしまいます。これを単純に0とするシンプルなやり方はないでしょうか?この場合は foreach my $num1 (@num1) { my $num2 = shift @num2; if ($num1) { printf "%+d%+d\n", $num1, $num2 } else { printf "0%+d\n", $num2 } } とすることで満足する結果となりますが、複数の数値部分で+0となるのを回避したい場合など、このようなif文でやると変に複雑なスクリプトになると思うのですが、そうするしかないでしょうか?

    • ベストアンサー
    • Perl
  • join と split で文字列を操作する場合

    にんにちは、 うまく解決する方法を思いつかないので、質問させてください。 以下のスクリプトを実行すると、a から z を * で join して、 その後、* で split するかなと思ったら、split は正規表現として とらえるためでしょうか、エラーになります。 #! /usr/bin/perl -w use strict; my $a = '*'; my $b = join $a , ('a'..'z'); print "$b\n"; my @result = split /$a/,$b; print "$_\n" foreach @result; exit(); $a = '\*'; にすると、split したときに、 余計な \ が残ってしまいます。 任意の(書く時点では分からない)いろんな文字列で 連結したり分割したりする場合のスマートな方法が ありましたら、教えていただけませんか? Perl 5.8 です。お願いします。

    • ベストアンサー
    • Perl
  • perl 初心者です。 わかりやすくお願いします。

    Perlを始めたのですが、本や色いろんなサイトを見てもよく分かりません。 Aと言うデータを読み込んで最大最小・平均・標準偏差を求めたいです。 (1)どこが間違っているのか1部づつでもいいので詳しく教えてください。 (2)一つ一つの意味がちゃんとはつかめていないと感じるので流れを教えてください。 #!/usr/bin/perl # 12345 STDIN use strict; use warnings; open ( FILEHANDLE , " < A " ) ; my @Str=<STDIN>; foreach my $Row (@Str ){ print $Row; } my $Minimum=$ARGV[0]; my $Maximum=$Minimum; my $Sum=$Minimum; my $temp=0; my $i=1; while ( $i < $Num_arg){ $temp=$ARGV[$i]; if ( $Minimum > $temp ) { $Minimum = $temp; }elsif ( $Maximum < $temp ){ $Maximum = $temp; } $Sum = $Sum + $temp; $i++; } my $Average = $Sum / $Num_arg; my $w = foreach my $w(0..$#Numbers){ ($Num_arg - $Average) ** / Num_arg; } my $Standarddivitation = sqrt ($w); print "Average value = $Average \n"; print "Maximum Value = $Maximum \n"; print "Minimum Value = $Minimum \n"; print "Standard devitation = $Standarddevitation;

  • プリントすると 保存位置が表示される

    %classをプリントしたいのですが、 保存位置が表示されるだけで肝心の中身が出てきません。 どうしたら 表示できますか? 前略 push @{$class{$name}->{grade}}, @grade とやって保存し、以下で表示させようとしました。 foreach my $key (sort keys(%class)) { print "$key:"; my @values = %{input{$key}}; print join',', @values; print ".\n"; }

  • TCP/IP Soket 通信

    本当に泣きそうです。教えてください。 サーバには   str_len=read(clnt_sock,msg_num,sizeof(msg_num));   msg_num[str_len]=\'\\0\';   printf(\"%s \\n\",msg_num);   str_len=read(clnt_sockt,msg_file,sizeof(msg_file));   msg_file[str_len]=\'\\0\';   printf(\"%s \\n,msg_file\"); クライアントには   write(sock,msg_num,sizeof(msg_num));   write(sock,msg_file,sizeof(msg_file)); になっていますが、お互いに実行させると、 サーバ側に「msg_num」は出力しますが、 「msg_file」は出力されず、待機状態になるのです。 どうすればいいのでしょうか?

  • PHP+MySQL 内部結合(INNER_JOIN)がうまく行きません。

    以下の文で「client_master」テーブルと「jobmaster0717」テーブルを内部結合させようとしているのですが、うまく行きません。どこがおかしいのでしょうか? <?php  // データベースサーバへの接続・データベースの選択  $db = mysql_connect('localhost','test','password');  $db_name = 'test';  mysql_select_db($db_name,$db);  // 処理対象テーブル  $tbl_name1 = "client_master";  $tbl_name2 = "jobmaster0717";    // 内部結合(INNER JOIN句)  $str_sql1 = "SELECT * FROM {$tbl_name1}"       . " INNER JOIN {$tbl_name2}"       . " ON {$tbl_name1}.company_ID"       . "  = {$tbl_name2}.client_ID;";  $rs1 = mysql_query($str_sql1,$db);  print "\"{$str_sql1}\"<br>\n";  // 結果セットの表示  show_rs($rs1,$db);  print "<br>\n";  // 結果セット(結果ID)の開放  mysql_free_result($rs1);    // データベースサーバの切断  mysql_close($db); ?>

  • n-gramの手直し

    プログラミング歴3週間ですが、n-gramのプログラミングを 作ってみましたが、うまく動きません。結果が「可愛い」 「あの子」「デートしたい」とならないといけないののですが、 どなたか優秀な方に手直しをお願いしたいと思います。よろしく お願いいたします。 my $a = "可愛いあの子とデートがしたい"; my $b = "あの子可愛いよね。デートがしたい"; $len1 = length($a); $len2 = length($b); my $i = 0; while($i < $len1) { if (0 == ($i % 2)) { $re1 = substr($a, $i, 2); my $j = 0; while($j < $len2) { if(0 == ($j % 2)) { $re2 = substr($b, $j, 2); } $j++; if($re1 eq $re2) { @word1 = ("$re1"); $num1 = push(@words, @word1); $count++; last; } } } $i++; if(0 == ($i % 2)){ if($re1 ne $re2){ if($count > 0) { @word2 = ("\n"); $num2 = push(@words, @word2); $count = 0; } } } } my $rewords = join('', @words); print $rewords;

    • ベストアンサー
    • Perl
  • SQLが応答しなくなっているのか、CGIが読み込み中のままになってしまいます。

    SQLを約1600回実行したら、5秒後にページを再読み込みします。 print "<html><body onload=\"setTimeout('location.reload()',5000)\">"; foreach ... {   ...   # 約1600回繰り返す   @result = select("SQL文");   ... } sub select{   my @result = ();   my($dbh, $sth);   $dbh = DBI->connect('DBI:mysql:データベース:localhost', "ID", "パスワード") or return 0;   $sth = $dbh->prepare("$_[0]");   $sth -> execute() or return 0;   $num_rows = $sth->rows;   $num_of_fields = $sth->{NUM_OF_FIELDS};   $result[0] = $sth->rows;   for ($i=1; $i<=$num_rows; $i++) {     @fetchrow_array = $sth->fetchrow_array;     $result[$i] = join ',', @fetchrow_array   }   $sth -> finish();   $dbh -> disconnect();   return @result; } 最初の1,2回は期待通りに動くのですが、 2,3回ほど再読み込みをすると、「読み込み中」のままになってしまいます。 (期待通りに動く場合、1回の読み込みは20秒程度です。) タスクマネージャを見ると、 期待通りに動いているときは、CPU使用率が60%くらいになっていますが、 「読み込み中」のままの時は1%程度になっています。 SQLサーバーから応答がなくなっているのでしょうか? (簡単なSQLにしてみても同じでした。) 原因がわかる方、よろしくお願いします。 WindowsXP SP2 Apache1.3 ActivePerl5.6 MySQL3.23

    • ベストアンサー
    • CGI