if($a =~「1~20」までの数字又は「1_1~1_20」~「20_1~20_20」までの数字){
OK;
}else{
NO;
}

を正規表現や条件分岐を使って範囲指定したいのです。

[1-9]
ですと111等も対象になりますし、{n,}とした場合でも数値の1~20までとは出来ないようで・・・。
また正規表現では_の扱いが今一わからない状況で
更に()と?を使って思考錯誤を繰り返しているうちに
[]//の用途がだんだんと分からなくなってしまいました。

各用途については調べ整理しているつもりなのですが
今回のようなケースに関して参考になる例を見つけられず質問させて頂きました。

ご掲示頂けませんでしょうか。宜しくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (5件)

No.2 です。

プログラムが動作しなかったとのこと、失礼しました。

後者のプログラムについては、"if( (" の2つの左カッコのうちひとつが余計でした。また、プログラムを投稿する際に、インデントをそろえるために各行のはじめの空白文字に全角を使ったことも問題の一つであったのかもしれません。

いずれにしても、失礼しました!
    • good
    • 0
この回答へのお礼

お忙しい中、わざわざご連絡有難うございます。

ご掲示頂きました内容を再度確認しました所、
前者のは仰る通り全角の空白の為だったようです。
後者のも仰る通りで(が一つ余分と全角の空白になっていたようでした。

内容については、正規表現部分につきましてはBLUEPIXY様のご解説を前提にしている事もあり理解しやすいプログラム内容と拝見する事ができました。

また考え方としまして例を2例もあげて頂き、正規表現だけで解決するのではなく条件分岐を取り入れた形で実現して頂き凄く感謝していますしとても参考になっています。

私自身まだまだ初歩的な事を見落としていて恥かしい限りですが、今回の件を良い機会と受け止め今後の励みに頑張りたいと思います。

この度はbender様にも感謝の気持ちで一杯です。

最後までお付き合い頂き有難うございました!

お礼日時:2005/05/09 18:13

#3>各細部についての意味


/^(?:[1-9]|1\d|20)(?:_(?:[1-9]|1\d|20))?$/
/^~$/
^:先頭から
$:最後尾までの間
にある、つまり、今回の対象文字列だけが入っている。(他の文字列に埋もれているのを対象としているのではない)
(?:~):グループ化する、()と違うのは$1などに値を設定しないこと、単にグループ化する時に使う。
[1-9]:1から9までの一文字を表す
\d:[0-9]の意味
[1-9]|1\d|20:|は、orの意味、1~9であるか10~19(1で始まる0~9)であるか20であるの意味
(~)?:~が0回または1回ある
    • good
    • 0
この回答へのお礼

お忙しい中、親切丁寧にご解説頂きまして本当に有難うございます。

本当に本当に感謝の気持ちで一杯です。

最初解説頂いてる部分を拝見した時、
^:先頭から・・・の:がえ?
更に
$:の:も、ん?・・・みたいに思ったのですが、

アサーションを利用した形のグルーピングの使い方
や、_を(?:_(~))とする辺りは思わず、「そっか~なるほど~」と思わされる瞬間でつい感動してしまいました。

この辺りは自分の経験の浅さから考えがそこまで及ばず中々自分の主観からは逃れられないもんだなぁ・・と自覚さえしてしまいますが、同時に凄いなぁ~有り難いな~と思う反面認識が広がった事に感動してしまいました。

この度はご教授頂きました事、本当に感謝しています。

有難うございました!!

お礼日時:2005/05/09 17:22

#1の方と同じです


if($a =~ /^(?:[1-9]|1\d|20)(?:_(?:[1-9]|1\d|20))?$/){
    • good
    • 0
この回答へのお礼

お忙しい中とても参考になる形でご掲示頂きまして、本当に有難うございました。

当初希望していた問題を解決できました。

各細部についての意味につきましては、おおよその検討しかつけようがないのですが、今回を機に正規表現について改めて調べ再勉強する良い機会になりました。

今後も事あるごとに振り返り、長期的な視野で正規表現を自分のものにしてゆけるよう頑張って参りたいと存じます。
この度は本当に感謝の気持ちでいっぱいです。
有難うございました。

お礼日時:2005/05/09 00:44

すでに丁寧な回答が寄せられているのですが、私は以下のような場合にわけて考えました。


(1)変数 $a の中が数字だけの場合
(2)変数 $a の中が「数字_数字」の形の場合
さらに、(1)の場合、その数字が1から20の範囲か、また、(2)の場合については、2つの数字が両方とも範囲内か、を調べるようにします。


if( ( $a=~/^(\d+)$/ && # (1)
   $1>=1 && $1<=20 ) ||
  ( $a=~/^(\d+)_(\d+)$/ && # (2)
   $1>=1 && $1<=20 &&
   $2>=1 && $2<=20
  ) ) {
 printf("yes\n");
} else {
 printf("no\n");
}

もしくは、

if( ( $a=~/^(\d+)(_(\d+))?$/ &&
   $1>=1 && $1<=20 &&
  ( $2 eq "" || $3>=1 && $3<=20 )
 ) {
 printf("yes\n");
} else {
 printf("no\n");
}
    • good
    • 0
この回答へのお礼

お忙しい所、貴重なご意見有難うございました。

私のほうで試行錯誤を重ねてみたのですが、折角ご掲示頂いた上記の2点の例はエラーになり自力では動作確認をする事ができませんでした。

この度はお時間割いてご掲示頂きまして有難うございました。

お礼日時:2005/05/09 00:33

面倒ではあるのですけど、この程度までなら、正規表現だけでなんとかなります。


1~20の数字を表す正規表現は・・
(?<!\d)([1-9]|1[0-9]|20)(?!\d)

連続した数字だけを取り出すために、ゼロ文字幅アサーションを利用するのが、ポイント。あんまり初心者向けの解説には載ってないので、こういう際に覚えてしまいましょう。
あとは、組み合わせてやってみてください。
    • good
    • 0
この回答へのお礼

ご返信の方遅くなったんですけれども、参考になる例とあわせて素早いご反応を頂き有難うございました。

また更にアサーションという概念がある事を知る機会を頂きましてありがとうございました。この件についてはまたおりをみて調べ取り組みたいと思います。

今回はご掲示頂きました正規表現で1~20までの数を対象にできた事は私には凄く感動的でした。

試しに自分で試行錯誤してみたのですが、1_20や1_2_3などまでひっかかってしまうようでした。

自分としてはイメージ的には下記のような形を想定しているのですが、まだ良くわかっておらず認識のあまさからうまく機能しないみたいです。
(?<!\d)([1-9]|1[0-9]|20)(?!\d)?(_)?(?<!\d)([1-9]|1[0-9]|20)(?!\d)

もしまたお時間などございましたら、アドバイスなど頂けましたら幸いです。

今回は大変参考になるご意見有難うございました。

お礼日時:2005/05/09 00:05

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QPHPと正規表現とワイルドカードについて

まずググってみたのですが、PHPを問わずあまり正規表現やワイルドカードについて書かれてあるサイトが見つかりませんでした。
ほとんどが質問であって、正規表現やワイルドカードについて詳細な情報が掲載されているサイトは見つかりませんでした。
なので、ここは1冊そういう専門の書籍を購入するしか手段はないのか、と悩んでいます。
他には、正規表現やワイルドカードがPHPのプログラムを書くのにどれだけ必要なのか。
ZENDのPHP認定資格の試験問題にも正規表現についての問題はあまりないのではないか、という気がしています。
皆さん、どこで正規表現やワイルドカードの知識を得ているのでしょうか。
また、PHPをやっていくのにどれだけ重要性があるのか知りたくて質問しました。
どうぞ宜しくお願い致します。

Aベストアンサー

>正規表現やワイルドカードについて詳細な情報が掲載されているサイトは見つかりませんでした。
ググるとトップに出るWikipediaに載ってますよ。

あと、普段使わない言語の正規表現仕様が知りたくなったら、ここを見ています。まあ、言語で機能有り無しが違うような機能を使うことは少ないと思いますけど。
http://www.kt.rim.or.jp/~kbk/regex/regex.html

>また、PHPをやっていくのにどれだけ重要性があるのか知りたくて質問しました。

一度覚えればいいだけなので、よく知らなければ一度おちついてじっくり取り組めばいいかと。よく使う物だけ覚えればいいし。
. * + ? *? +? [ ] ^ $ { } ( ) \ くらいで十分です。

Q1_1から1_5へカウントアップ後、2_1から1_5へカウントアップしたい

お世話になります。
題名にあります通りなんですが、1_1から1_5にカウントアップしたら
2_1から2_5へとカウントアップするようなスクリプトを考えているのですが
下記の例ですと、1111122222333334444455555となってしまいなす。
どなたか良きアドバイス頂けないでしょうか。宜しくお願いします。
@list = (0, 1, 2, 3, 4, 5);
foreach $b(@list) {
for ( $a = 1 ; $a <= 5 ; $a++ ) {
print "";
print "$a_$b\n" ;

} }

Aベストアンサー

foreach my $first (1..5) {
foreach my $second (1..5){
print "${first}_$second\n";
}
}

こんな感じの処理でしょうか?

Qワイルドカードと正規表現って何が違うのでしょうか?

ワイルドカードは簡単な文字検索方法で
正規表現は難しいパターンも調べられる文字検索方法ですか?

Aベストアンサー

「ワイルドカードと正規表現」じゃなくて、「ファイル名のマッチと正規表現」の事ですかね。

ワイルドカードはトランプ用語で、「他のどんなカードの代わりにも使えるカード(多くの場合ジョーカー)」のことです。そこから転じて、「他のどんな文字にもマッチする特殊文字」の意味で使われます。

ファイル名のマッチ: コマンドラインや、プログラミング言語の一部の関数でのファイル名の指定に使う
 ? どんな1文字にもマッチ(ワイルドカード)
 * 0文字以上のどんな文字列にもマッチ(文字列のワイルドカード)
 Windowsで使えるのは上記2つですが、Unix/Linuxのシェルだともう少しあります。

正規表現: プログラミング言語から様々な文字列パターンを選択するときに使うパターン
 . どんな1文字にもマッチ(ワイルドカード)
 * 直前の表現の0回以上の繰り返し(繰り返し指定子の一つ)
 他に多数あり。

それぞれ使い場所が違います。

Q$hts =~ s/##([^#]+)##/$FORM{$1}/g の意味を教えてください!

お世話になります。
perl素人なのですが必要に迫られてWEBで調べながら
ソースを解析していますが、次のコードで完全に止まってしまいました。

$hts =~ s/##([^#]+)##/$FORM{$1}/g

この場合、
#hts から ##([^#]+)## を探して $FORM{$1} に全て置き換えようとしていると思うのですが、以下2点が理解できず困っています。

1.##([^#]+)## の意味
$htsに##で囲まれた文字列が複数あるのでそれら全てを探すということでしょうか?

2.$FORM{$1} の意味
$1は1.で検索した結果だと思いますが、$FORM{ }は一体なんでしょうか?

素人がいきなり解析するのは無謀なのは承知の上ですが、
どうしても業務で必要なので、お知恵をお貸し下さい。
よろしくお願いいたします。

Aベストアンサー

1.
perlを基準に「正規表現」で調べてごらん

2.
同じくperlでHTMLのformデータを受け取る方法を調べてごらん

Q正規表現とワイルドカードについて

UNIX初心者の者です。現在Solarisを使い毎日悪戦苦闘しています。
質問なのですが、「正規表現」と「ワイルドカード」とはどのように違うものなのでしょうか。ちょっと混乱しています。
現状の認識では、
「ワイルドカード」-コマンドラインで使うもの。エスケープするときは「’’」で囲む。複雑な指定は難しい。
「正規表現」-コマンドの引数や、スクリプトなどで使われるもの。エスケープするときは「¥」をつける。基本的に「’’」で囲むもの。様々な表現が可能。
といった感じにとらえています。が、いざ使うとなると混乱している状態です。
すみませんが、この2つについて教えてもらえないでしょうか。
あと参考になるような本やホームページなどもあるでしょうか?コマンドの組み合わせやシェルスクリプトの記述なども勉強中なので、その関係の事でもよいので。
よろしくお願いします。

Aベストアンサー

正規表現(Regular Expressions, RE)は使いこなすと便利ですよね。

>「ワイルドカード」-コマンドラインで使うもの。エスケープするときは「’’」で囲む。
>複雑な指定は難しい。
実際にはシェルスクリプトでも使えますが、ワイルドカードの展開はシェルの仕事だから
Cプログラムでは処理する必要はないし、だいたいそういう認識でいいのでは。
「''」で囲むというのはワイルドカード自身の属性というよりは
コマンドラインでシェルが展開してくれるのを防ぐためですね。

「ワイルドカード」とはもともとトランプ用語で、どのカードの代わりにも使える
オールマイティなカードを指したもので、これから転じて
file000.jpg, file001.jpg,...file999.jpg というファイルがあるとき
「file*.jpg」とか「file???.jpg」「file[0-9][0-9][0-9].jpg」などという指定ができるのが
シェルのワイルドカードで、ここまではご存じと思います。

Solaris のシェルというと Bourne Shell(sh)でしたっけ。Linux の bash など
モダンなシェルよりは機能的に劣ります。
sh ではどのみち複雑な指定はできないのでざっと流しても構いません。
また、bash のような高機能シェルだったら help コマンドでオンラインヘルプが見られます。

シェルのワイルドカード(グロビング)については、アスキーの
「たのしい UNIX」「続・たのしい UNIX」(坂本文)が参考になるでしょう。
また、やはりアスキーの「UNIX プログラミング環境」(Kernighan&Pike著、石田晴久訳)も
古き良き UNIX 文化を伝える不朽の名著ですから、かえって Solaris の sh では
素直に使えるかもしれません。シェルスクリプトから高度なCプログラミングの勉強にも
もってこいです。
ここでも興味深い質問がありましたので、ぜひご覧ください。
No.483118 質問:シェルスクリプトに手をだしてみたいのですが。。。
http://oshiete1.goo.ne.jp/kotaeru.php3?q=483118

>「正規表現」-コマンドの引数や、スクリプトなどで使われるもの。
>エスケープするときは「¥」をつける。基本的に’’」で囲むもの。様々な表現が可能。

よく勉強してらっしゃいますね。正規表現はワイルドカードよりずっと柔軟な表現が可能で
その気になれば分厚い本が一冊書けてしまいます。
事実、オライリーから「詳説 正規表現」(Jeffery E. F. Friedl 著、歌代和正他訳)
という大部が出ています。
http://www.amazon.co.jp/exec/obidos/ASIN/4900900451/249-6496763-3526725
オライリー・ジャパンのサイトになかったとこを見ると、第2版が近々出るのかな?

また正規表現の文法にはさまざまな方言があって、grep, sed のような単純なもの
(BRE, Basic RE)や egrep, awk のように多少拡張されたもの(ERE, Extended RE)
などありますが、現在最有力なのが Perl5 のものです。
Python や Ruby といった後輩スクリプト言語や Java 1.4 の正規表現も
Perl5 互換を目標としています。

正規表現は文字列処理の「肝」ですので(これを軽視しているMSソフトが信じられない!)
解説しているサイトはたくさんあります。
参考 URL の正規表現リンク集からいくらでもたどれますが、
2番目の「Riue ちゃんの正規表現講座」が初心者向けでしょうか。
おさらいには以下の「正規表現メモ」がいいかと思います。
http://www.kt.rim.or.jp/~kbk/regex/regex.html
また、「Perl 正規表現雑技」をご覧になれば、素因数分解までやってのける
正規表現のパワーに瞠目されること間違いありません。
http://www.din.or.jp/~ohzaki/regex.htm

このように、正規表現が最も威力を発揮するのは Perl などの
スクリプト言語ですので、Perl 関連のサイトやドキュメントをご覧になれば
いっそう勉強が進むと思います。長くなってしまいましたが、
美味しいとこだけつまみ食いして、できるところから始めればいいのです。
健闘を祈ります(^^

参考URL:http://www2.famille.ne.jp/~akio1998/l_grep.html,http://www.sixnine.net/regexp/

正規表現(Regular Expressions, RE)は使いこなすと便利ですよね。

>「ワイルドカード」-コマンドラインで使うもの。エスケープするときは「’’」で囲む。
>複雑な指定は難しい。
実際にはシェルスクリプトでも使えますが、ワイルドカードの展開はシェルの仕事だから
Cプログラムでは処理する必要はないし、だいたいそういう認識でいいのでは。
「''」で囲むというのはワイルドカード自身の属性というよりは
コマンドラインでシェルが展開してくれるのを防ぐためですね。

「ワイルドカード」とはもと...続きを読む

Q正規表現のm{}

正規表現の記述で、m{}と書くサンプルを目にしたのですが、このmと中括弧は何を意味するのでしょうか?

以下、Hタグにマッチするかをテストする正規表現のサンプルです。
$_ = "<H3>ヘッダ3</H3>";
if ( m{<(H\d)>(.+)</\1>} ) {
print "found!!";
}

Aベストアンサー

「m」は正規表現マッチで、
通常の /・・・・/ と基本的に同じ働きです。
違うところは、mの後に非英数字や各種括弧(), <>, {}, []を使って、
正規表現を括ることができることです。
すなわち、
 /abc*/
 m#abc*#
 m{abc*}
などは、全部同じ意味です。
スラッシュがたくさんはいる正規表現を書くときなど、いちいちエスケープしなくて良いので便利、ですね。

Q正規表現とワイルドカード

この二つは使用に違いがあるのはわかるのですが、どのような時に使い分けるのでしょうか?
調べて見たのですが、シェルによるとかコマンドによるとか書かれていましたがいまいちよくわかりません。
こういうときは正規表現、こんなときはワイルドカード、という風に使い分けに違いがあれば教えて下さい。

Aベストアンサー

シェルは「*」などのメタキャラクタを扱う際、自分なりのルールに則って解釈していきます。このシェルの解釈の仕方をワイルドカードといいます。シェルはメタキャラクタを正規表現として扱いません。これは仕様です。

> こういうときは正規表現、こんなときはワイルドカード、という風に使い分けに違いがあれば教えて下さい。

故に「使い分け」とは意味合いが少しばかり違うのです。どちらかというと「使い方」に気を配る、というイメージでしょうか。
コマンドラインを管理するのはシェルです。ということは、コマンドラインに出現するメタキャラクタはすべてシェルがワイルドカードとして展開します。

ただし、grep, sed や awk など一部のコマンドはその性質上、引数の全て、あるいは特定の部分に指定された文字や文字列を正規表現として解釈します。これも仕様です。

よって、正規表現を扱うコマンド、即ち上記 grep などがコマンドライン中に「*」や「$」などのメタキャラクタを伴って登場した際、シェルとの争奪戦になります。そこでクォーティングなる気配りが必要になります。

とは言うも、このメタキャラクタの解釈には順序というものがあり、先にコマンドライン全体を解釈するのはシェルである、ということを知っておくとより理解が深まると思います。

シェルは「*」などのメタキャラクタを扱う際、自分なりのルールに則って解釈していきます。このシェルの解釈の仕方をワイルドカードといいます。シェルはメタキャラクタを正規表現として扱いません。これは仕様です。

> こういうときは正規表現、こんなときはワイルドカード、という風に使い分けに違いがあれば教えて下さい。

故に「使い分け」とは意味合いが少しばかり違うのです。どちらかというと「使い方」に気を配る、というイメージでしょうか。
コマンドラインを管理するのはシェルです。ということ...続きを読む

Q$in{'~'}を$~に変換

CGIを改造中です。
変数の処理なのですが、サブルーチン内で利用するときに「$in{'~'}」と言う形でしか表示してくれません。これを「$~」の形にしたいです。
数が少なければ「$~ = $in{'~'}」を個数書けばいいのでしょうけど、結構数があるので、何か簡単な方法で変換できないかと考えています。
良い方法があれば教えてください。

Aベストアンサー

ハッシュのままで何か不都合があるのかなと
疑問に思いつつ・・・
#実際ハッシュは
#「(変数の)値に別の値を対応させる」
#ために存在するわけだから

けど,まあ,やろうと思えばkeys関数でできますよ.

%in=(
'X' => 1,
'Y' => 2,
'Z' => 3,
);

for $key (keys %in){
${$key}=$in{"$key"};
print "key; $key ${$key}\n";
}

print "$X $Y $Z";

strictとwarningsのプラグマを外さないといけないので
副作用の方が大きいでしょうが.

QCSSのクラス名・ID名の指定でワイルドカードか正規表現を使いたい

CSSでクラス名やID名を指定する場合に、
ワイルドカードか正規表現を使いたいと思ったのですが、うまくできません。
使えないのでしょうか?

また、他に、似たクラス名・ID名を一括で指定する方法はありますか?

例)
<div id="cat1">猫が1匹</div>
<div id="cat2">猫が2匹</div>
<div id="cat3">猫が3匹</div>

#cat1, #cat2, #cat3{color:#FF00FF;}

#cat*{color:#FF00FF;}
のようにまとめて指定したい。

Aベストアンサー

CSS2までのセレクタにはワイルドカードも正規表現も使えません。

※ CSS3では属性セレクタが拡張されているので
div:[id^="cat"] {~~~} ・・・・ idがcatで始まるdiv要素
みたいな事もできますが、まだ使えるブラウザが限られるので現実的ではありません。

http://hp.vector.co.jp/authors/VA022006/css/selector.html
http://www.google.com/search?q=css3+%83Z%83%8C%83N%83%5E&hl=ja

Q@{$protocol_name}

usr strict;
をつかって、

$protocol_name = "pppoe";

@{$protocol_name}

のような使い方をしたいと思っていますが、

Can't use string ("pppoe") as an ARRAY ref while "strict refs" in use at ./ctest.pl line 152, <RCFG2> line 7

のようにエラー表示がでてしまいます。
どうしたら回避できるでしょうか。

Aベストアンサー

@pppoe という配列を生成する段階でハッシュ等扱いやすい変数に格納しておくのが定石だと思います。

・ハッシュにハードリファレンスで格納する方法
$protocol{pppoe} = \@pppoe; # 代入
@{$protocol{$protocol_name}} # 参照
# @pppoeとしましたがもちろん無名配列でかまいません。

・分岐させる方法
if($protocol_name eq "pppoe"){
... = @pppoe;
}elsif ...

・シンボリックリファレンスだけ許可させる方法
no strict 'refs';

・%main::から引く方法
@{$main::{$protocol_name}}


人気Q&Aランキング

おすすめ情報