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

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

A 回答 (1件)

シェルは「*」などのメタキャラクタを扱う際、自分なりのルールに則って解釈していきます。

このシェルの解釈の仕方をワイルドカードといいます。シェルはメタキャラクタを正規表現として扱いません。これは仕様です。

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

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

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

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

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

非常にわかり易い回答、ありがとうございました。
頭の中が整理できました。
ありがとうございました。

お礼日時:2007/07/03 07:20

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

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

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

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

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

Q正規表現でのパイプ(or)を減らしたいのですが

いつもお世話になっています。
正規表現のパイプ(|)は非常に遅くなるらしいので、[]内に並べるようにプログラムを修正しようと思っています。それで、
/a|b|c/ ---> [abc]
のような方法は、よく紹介されているのですが、a,b,cが単独文字ではなく、単語になっているような場合、
/abc|def|ghi/ ---> [(abc)(def)(ghi)]
だと多分ダメですよね(今実行環境が無く確認できません)。
それで、各々の単語を
$a = 'abc';
$d = 'def';
$g = 'ghi';
のようにあらかじめ定義しておいて、
/$a|$d|$g/ ---> [$a$d$g]
というように書き換えると、うまくいくのでしょうか?
やり方が間違っていましたら、ご指摘いただきたく、よろしくお願いします。

Aベストアンサー

ブラケットの中は独立したキャラクタとして扱われるので文字列をそこに収めることはできません。
#これは#1の方の回答にもあるとおり

そんなに気になるのなら
Regexp::Optimizer - optimizes regular expressions - search.cpan.org
http://search.cpan.org/~dankogai/Regexp-Optimizer-0.15/lib/Regexp/Optimizer.pm
このモジュールを使ってみるとか。

正規表現のマッチングを遅くする原因は色々あるので、
本当にその辺を知りたければ

oreilly.co.jp -- Online Catalog: 詳説 正規表現 第2版
http://www.oreilly.co.jp/books/4873111307/

を頑張って読破しましょう。

Q正規表現

$ grep -E ^a.*$z abc.txt

ある書籍の中で、上記のコマンドでマッチする文字列として、
"az"が挙げられているのですが。
"."は一般に任意の1文字と説明されていますが、"az"では"."がゼロ文字として扱われているように思えるのですが。任意の1文字にはゼロ文字も含まれるのでしょうか?

Aベストアンサー

"."だけならゼロ文字の時はマッチしませんが、
"*"が、「直前のパターンの0回以上繰り返し」という意味なので、
".*"で、「長さ0以上の任意の文字の列」という意味になります。

ところで、
"^a.*$z"
ではなくて
"^a.*z$"
ではないでしょうか?

Q【Ruby or Perl・正規表現】ある文字列の先頭5文字を残して削除するには?

初心者質問で恐縮です。
RubyもしくはPerlで、ある文字列の先頭5文字を除く文字をすべて削除する(先頭5文字のみの文字列にする)には、どのような記述をすればよいでしょうか。
教えていただけるとうれしいです。
よろしくお願いします。

Aベストアンサー

Perlなら

s/^(.....).*$/$1/;

でいけるように思います。

Q正規表現について

正規表現について

LPIC黒本の問題で1つ困っています。
$ grep -E ^A[^A]A[^A] lpic.txt
にマッチする文字列
答え
AaAa
となっていますが理解できません。

そもそも正規表現ってなんでしょうか?
あまり難しいようなら飛ばしますが、
となたか教えてくれるお方おりましたらお願いいたします。

Aベストアンサー

grep -e 正規表現 ファイル名
というLinuxのコマンドはいいですよね。

正規表現となるのは、^A[^A]A[^A]ですが、

・最初の^は、文字列(行)の最初にマッチすることを指示しています
・[^A]はA以外の文字を表しています
 [ ]は、[ ]内に含まれる一文字にマッチすることを、
 [ ]内の^は、それを否定します
 すなわち、Aでない文字を指しています

以上から、
行頭の、A*A*(*はA以外の文字)
となります。

lpic.txtの中身がわかりませんが、おそらく、AaAaという文字が
入っているのでしょう。

こういったことは、正規表現の文法をまとめたサイトに出ています
例えば
http://www.komonet.ne.jp/~perl/chap7.htm

正規表現というのは、文字列を検索したり置換したりするための
文法ですよね。
試験ではどうか知りませんが、実際にはものすごく使うテクニック
です。
プログラムにかかわらず、テキスト原稿の中の特定の文字を一括
で修正したり、データベースのデータを一括で修正したり・・・

あいまいな文字列の中から、特定の文字列を探し出すための有効
なテクニックとして認知されています

grep -e 正規表現 ファイル名
というLinuxのコマンドはいいですよね。

正規表現となるのは、^A[^A]A[^A]ですが、

・最初の^は、文字列(行)の最初にマッチすることを指示しています
・[^A]はA以外の文字を表しています
 [ ]は、[ ]内に含まれる一文字にマッチすることを、
 [ ]内の^は、それを否定します
 すなわち、Aでない文字を指しています

以上から、
行頭の、A*A*(*はA以外の文字)
となります。

lpic.txtの中身がわかりませんが、おそらく、AaAaという文字が
入っているのでしょう。

こういった...続きを読む

Q言語ではなく、正規表現のみで複数の条件を記述する方法 ?

一つの条件の正規表現は書けるようになりましたが、
条件が重なった場合の対処の仕方がわかりません。

my $val = "12";
#数字のみ
if($val =~ /^[0-9]+$/){
# match!
}

#0で無い
if($val !~ /^0$/){
# match!
}

# 数字で0でない <---複数条件



# 言語でカバーするのではなく、正規表現のみ(1つの正規表現)
# でANDやORやXORができるパターンの記述方法が知りたいです。
if($val =~ /^[0-9]+$/) && ($val !~ /^0$/){
# match!
}

Aベストアンサー

条件式の AND や XOR に相当するものは、正規表現には存在しません。というのも、正規表現で表すのは「パターン」であり、「条件」ではないからです。
※OR についてはパターンの選択を行う | が相当します。

このため、複数の条件式にしたくない場合は、1つで複数の条件を満たすパターンを書くしかありません。また、汎用的な方法もないので、ケースごとにパターンを書き下ろさなければなりません。

No.2 補足より
> 言語を使った&& ||ではスマートではなく、複雑な内容になってきた場合、1行で解決できた方が発展性があるかと思いましてこだわっております。

確かに「0ではない数字」程度のことを複合条件にするのはスマートとは言えないでしょう。しかし、関連性のない事柄を無理なパターンで表現するくらいなら、分解して && や || で結合した方がすっきりします。
また、大概の場合、1行で無理に解決した方が発展性には欠けますので、発展性やメンテナンス性を求めるならば、あまりこだわらない方がよいでしょう。

Q正規表現*について

LPICレベル1 翔泳社の本を参考にして試験対策をしていますが、p121の0回以上繰り返えす*でab*zでマッチするのが「az」「abz」「abbz」とあります。しかし、「az」はlsコマンドで試してみましたが引っかかりません。
この本が間違っているのでしょうか?

シェルはbashを用いています。(REDHAT9)

回答のほどよろしくお願い致します。

Aベストアンサー

シェルによって違うというよりは「正規表現」と「シェルのワイルドカード」が違うんです。シェルのファイル名の展開に使用する * や ? や [a-z] のようなものは正規表現とは違います(強いて言えば簡略化された正規表現です)。また、だいたいの有名なシェルは Bourne Shell (sh) の影響を受けており、ワイルドカードの規則はほぼ同じです(というか私は違うのを知りません)。

> aではじまりzで終わるファイルをdir1/からdir2へ移したい場合

それは mv dir1/a*z dir2 で出来ます。
*の部分は0文字以上の任意の文字列です。(これを正規表現で書くとしたら.*になります)。

Q正規表現について

HTMLファイルを読み込み、特定の文字列にリンクを付けて出力したいのですが上手くいきません。

例: <img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。

 ↓正規表現をキーワードにしてリンクを付けたい。

正:<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に<a href="seiki_hyougen.html">正規表現</a>を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。

誤:<img src="./seiki_hyougen.gif" alt="<a href="seiki_hyougen.html">正規表現</a>についての説明">更に<a href="seiki_hyougen.html">正規表現</a>を知りたい方は、<a href="special.html"><a href="seiki_hyougen.html">正規表現</a>の詳しい説明</a>をクリックして下さい。


尚、下記URLのサンプルを参考にしてスクリプトを作成しています。
http://php.oss.eznetsols.org/manual/ja/function.preg-split.php

$r = preg_split('((\/a>)|(<a))', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 0; $i < count($r); $i++) {
if ($r[$i] == "<a") {
$i++; continue;
}
$r[$i] = preg_replace(
"/(正規表現)/i", "<a href='seiki_hyougen.html'>\\1</a>", $r[$i]
);
}
return join("", $r);

この(正規表現)の部分で上手い正規表現を使えばalt="×××"の中にリンクタグが入らないようにできるのでは?と思っているのですが・・・。

どうか、良い方法を教えて下さい。よろしくお願いいたします。

HTMLファイルを読み込み、特定の文字列にリンクを付けて出力したいのですが上手くいきません。

例: <img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。

 ↓正規表現をキーワードにしてリンクを付けたい。

正:<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に<a href="seiki_hyougen.html">正規表現</a>を知りたい方は、<a href="special.html">正規表現の詳しい説明...続きを読む

Aベストアンサー

ごめんなさい。複数のキーワードに対応しようとして
余計なことをしてしまいました。
訂正します。

<?php
$msg = <<<EOF
<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。
EOF;

$links = array (
'正規表現' => '<a href="seiki_hyougen.html">正規表現</a>',
);

$link_keys = array_keys($links);
$link_values = array_values($links);

# 表示用関数
function printandreturn ($str) {
print stripslashes("$str");
return "";
}

function printwithlink ($str) {
global $link_keys, $link_values;
print str_replace($link_keys, $link_values, stripslashes($str));
return "";
}

# 処理開始

# 文字化け対策
$msg = str_replace("\\", "\\\\", $msg);

# メインループ
while (strlen($msg)) {
# アンカー部分をスキップ
if (strpos($msg, '<a') === 0) {
$msg = preg_replace("|^(.*?</a>)|e", "printandreturn ('$1')", $msg);
continue;
}
# タグ部分をスキップ
if ($msg[0] == '<') {
$msg = preg_replace("|^(<.*?>)|e", "printandreturn ('$1')", $msg);
continue;
}

# 次のタグまでをリンク付きで表示
foreach ($links as $key => $value) {
$msg = preg_replace("|^([^<]+)|e", "printwithlink ('$1')", $msg);
}
}
?>

ごめんなさい。複数のキーワードに対応しようとして
余計なことをしてしまいました。
訂正します。

<?php
$msg = <<<EOF
<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。
EOF;

$links = array (
'正規表現' => '<a href="seiki_hyougen.html">正規表現</a>',
);

$link_keys = array_keys($links);
$link_values = array_values($links);

# 表示用関数
function printandr...続きを読む

Qシェルスクリプトの正規表現

こんばんは。

CentOSでサービスを再起動しようと思ったのですが、資料に書いてある
通りにスクリプトを作っても動きません(起動はできるけど
再起動、停止ができない)。
仕方がないのでプロセスをkillしたあとスクリプトを起動して再起動
する方法を取ろうとしていますが、最後の1歩で詰まりました。
echoでps -axをした結果を変数に入れて先頭の数字(PID)だけを
切り出そうとするのですが、プロセスIDが、空白+PID4桁の時と
空白なしPID5桁のときとあるので上手くHitさせることが出来ません。

mofu=`ps -ax|grep qmail-send`
4桁) mohe=`expr "$mofu" : \(^\s[0-9]*\)'`
5桁) mohe=`expr "$mofu" : \([0-9]*\)'`
kill $mohe
/etc/rc.d/init.d/qmail
シェルスクリプトで自動化したいので、PIDの桁数に関係なく確実に
killしたいです。
上手い方法があったら御教授下さい。
よろしくお願いします。

こんばんは。

CentOSでサービスを再起動しようと思ったのですが、資料に書いてある
通りにスクリプトを作っても動きません(起動はできるけど
再起動、停止ができない)。
仕方がないのでプロセスをkillしたあとスクリプトを起動して再起動
する方法を取ろうとしていますが、最後の1歩で詰まりました。
echoでps -axをした結果を変数に入れて先頭の数字(PID)だけを
切り出そうとするのですが、プロセスIDが、空白+PID4桁の時と
空白なしPID5桁のときとあるので上手くHitさせることが出来ません。

mofu=...続きを読む

Aベストアンサー

qmailはよくわからないのですがkillallは使えないのでしょうか?
また、/var/runなどにpidは保存されないのでしょうか?

Q正規表現について

今lexのプログラムを書いているのですが、正規表現の部分でつまずいてしまいました。perlの正規表現なら分かるのですが、lexと少しかってが違い困っています。lexの正規表現でコメント(プログラム中で/**/で囲まれた部分)を読み飛ばす時には、どのような正規表現にしたら是非教えてください。なお/**/の中には文字列*/は出てこないと過程していいとのことでした。
解答お願い致します。

Aベストアンサー

>できるだけ正規表現で表したいのですが・・・面倒ですよね(笑)
それはなぜですか?
もし自分自身の興味としてそうしたいのであれば、解答をそのまま教えて欲しいということはないですよね。

>なお/**/の中には文字列*/は出てこないと過程していいとのことでした。

何かの課題で出されていている問題で、その解答が欲しい?

んじゃあ考え方のヒントだけ。

xy を含まないものにマッチする正規表現
http://www.din.or.jp/~ohzaki/regex.htm#WithoutXY

の応用です(というかそのまま)。
/\* ('*/' を含まない文字列) \*/
という正規表現を、上のURLの先で説明されているパターンを適用してやればできるでしょう。

Qコマンド find の「繰り返し」正規表現

Debian 2.6.18 を使っています。

find で正規表現を使いたいのですが、上手くいきません。
やりたいこと自体は
find /foo/bar -maxdepth 1 -name '????????????????????????????????????????????????????????????????' -print
で実現しているのですが、これを例えば
find /foo/bar -maxdepth 1 -regex '/foo/bar/.{64}' -print
のように「繰り返しの回数」を指定する形で表現できないものでしょうか?
なお
find /foo/bar -maxdepth 1 -regex '/foo/bar/.\{64\}' -print
もやってみたのですが、ノーヒットで終了しました。

よろしくお願いします。

Aベストアンサー

気になったので GNU find のソースをほげってみました.
結論からいうと「繰り返し回数を指定する正規表現は (標準では) サポートしていない」ということのようです.
1ヶ所変更すればサポートできるんですが....


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング