正規表現について、おたずねします。

文字列 abc,def,ghi のいずれかにマッチする正規表現は (abc|def|ghi) ですよね。
それでは、「abc,def,ghi のいずれにもマッチしない」正規表現は、どう書けばいいのでしょうか?
あちこち調べましたが、どうしてもわかりません。

ただし、if $a =~ /(abc|def|ghi)/ などで、=~ を !~ に直す、というのはナシです。あくまでも右辺の式の中で表現したいのですが…

A 回答 (2件)

この場で、詳細に説明することは私には難しいので


割愛させていただきます。
#混乱させるだけになりますので。

ご自身でお調べいただくか、識者のご登場に期待してください。

ともかく、こんな感じでできているでしょうか?
#若干不十分かも知れません。

/(?=^(?:(?!abc).)*$)(?=^(?:(?!def).)*$)(?=^(?:(?!ghi).)*$)/s

それでは。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

例の通りにやってみたら、意図する動作ができました!

私も Perl を使って結構長いんですが、この ?= とか ?: とか ?! が、まだイマイチよく理解できないんですよ。ラクダ本見ても、例があまりなくてよくわからないし…

もう少し、あちこち当たって勉強してみます。

お礼日時:2002/02/16 20:40

/[^a]bc|[^d]ef|[^g]hi/ こういうのでしょうか^^;


一般的なのはPerl拡張正規表現
/(?!abc)|(?!def)|(?!ghi)/
みたいになるのでしょうか?^^;

意図している具体例を挙げて頂ければ、他の方法が良いかも知れませんが^^;

perl -e "$str = 'abdefgh'; $str =~ /([^a]bc|[^d]ef|[^g]hi)/; print $1 eq ''; "
perl -e "$str = 'abcdefghi'; $str =~ /((?!abc)|(?!def)|(?!ghi))/; print $1 eq '';

出力はいずれも1。ActivePerl (Build 630)で確認しました。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

> [^a]bc|[^d]ef|[^g]hi/

実際には abc/def/ghi というのはドメイン名(FQDN)でもっと複雑で長い文字列になるので、この方法ではちょっとダメそうです。

やはり ?: や ?! を使うのでしょうが、2番目の例は、こちらで試した限りでは、うまくいきませんでした。

もう少し、いろいろ調べてみます。

お礼日時:2002/02/16 20:44

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

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

Q@b = grep(/マッチパターン/, @a);でなく@a = grep(/マッチパターン/, @a);でOKについて

@b = grep(/マッチパターン/,@a);だと配列@aの中でマッチするものを探して@bに入れる・・・というのは理解できるんですが、
@a = grep(/マッチパターン/,@a);とし、
foreach $_ (@a) {
print $_;
}
で参照した場合、@aの中のマッチパターンにマッチするのだけ表示されますけれども、ここでマッチしないのは削除されるのでしょうか・・。

@aから@aにいれる・・・となる事について、どのように@aにマッチしたものを入れ、マッチしないものは削除されるのかの仕組みについて、ご説明できる方はいらっしゃいますでしょうか(例えば内部的にpopやshiftが機能していて・・・みたいな事なのかな・・とか思うんですけれども)

お手数ですが、ご存知の先生方ご教授願えましたら幸いです。

Aベストアンサー

#1でのTacosanさんの回答の1です。
つまり、
@a = grep(/マッチパターン/,@a);
これは
@aの内容を列挙→ grepに掛ける→条件に合うものだけのリストを作成→作成したリストを代入。
となります。
grepに掛かる前の@aの内容は、代入の際に「丸ごと」破棄されます。

perly.y
/* Binary operators between terms */
termbinop:term ASSIGNOP term /* $x = $y */
{ $$ = newASSIGNOP(OPf_STACKED, $1, IVAL($2), $3);
TOKEN_GETMAD($2,$$,'o');
}

op.c

OP *
Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
{
dVAR;
OP *o;

(略

if (is_list_assignment(left)) {
static const char no_list_state[] = "Initialization of state variables"


という具合なので、代入の左右両辺が同じ変数かどうかのチェックは多分やってません。

#1でのTacosanさんの回答の1です。
つまり、
@a = grep(/マッチパターン/,@a);
これは
@aの内容を列挙→ grepに掛ける→条件に合うものだけのリストを作成→作成したリストを代入。
となります。
grepに掛かる前の@aの内容は、代入の際に「丸ごと」破棄されます。

perly.y
/* Binary operators between terms */
termbinop:term ASSIGNOP term /* $x = $y */
{ $$ = newASSIGNOP(OPf_STACKED, $1, IVAL($2), $3);
TOKEN_GETMAD($2,$$,'o');
}

op.c

OP *
Perl_newASSIGNOP...続きを読む

Q正規表現のパターンマッチがうまくいきません。

正規表現のパターンマッチがうまくいきません。
入力した文字を含むデータを抽出しようとしているのですが、エラーは出ないものの、ヒットしません。

次の構文をそれぞれを試してみました。
目的は入力された文字$matchを含む$textを@queryに入れることです。

if($text =~ /$match/){ push(@query, $text); }
if($text =~ /\$match/){ push(@query, $text); }
if($text =~ /.*\$match.*/){ push(@query, $text); }
if($text =~ m/.*\$match.*/){ push(@query, $text); }

半角英数で何度か試したのですが、どれでやってもヒットしてくれません。
どこをどのように訂正すればいいでしょうか。
お分かりの方ぜひご指導ください。

ちなみによく入力データを$in{aaa}とか$QUERY{aaa}などとまとめることがあるのですが、これを正規表現にそのまま入れるにはどうしたらいいでしょうか。
{}は量指定子になるのでこのままではエラーになるかなとも思うのですが、\などでエスケープすればいいのでしょうか。
上の$matchも元々は$in{aaa}なのですが、
$match = $in{aaa}
として変えています。

正規表現のパターンマッチがうまくいきません。
入力した文字を含むデータを抽出しようとしているのですが、エラーは出ないものの、ヒットしません。

次の構文をそれぞれを試してみました。
目的は入力された文字$matchを含む$textを@queryに入れることです。

if($text =~ /$match/){ push(@query, $text); }
if($text =~ /\$match/){ push(@query, $text); }
if($text =~ /.*\$match.*/){ push(@query, $text); }
if($text =~ m/.*\$match.*/){ push(@query, $text); }

半角英数で何度か試したのですが、どれ...続きを読む

Aベストアンサー

形は一番上のものです. なぜヒットしないのかについては, $text や $match にどのような文字列が入っているかわからないのでなんとも言えません.
後半の質問は, 実際にやってみればたぶんやってみればわかる. ただしエスケープしちゃだめ.

QPerlの正規表現でマッチする範囲を限定

例えば、以下のようなことがしたいのですが可能でしょうか?

変数$bufに複数行の文字列が入っていたとしてこのうち、
タグとエレメント外を対象にしてマッチさせる
(例として以下のような文字列にしたい)

<a href="abcdef">abcdef</a><br>
<b>abc</b>defabcdef<br>
abcdef<b>abcdef</b><br>

↓(タグとエレメント外の文字aを<b>a</b>に置き換える)

<a href="abcdef">abcdef</a><br>
<b>abc</b>def<b>a</b>bcdef<br>
<b>a</b>bcdef<b>abcdef</b><br>

実際にはこのときのマッチの対象となる文字と文字数は可変で
bになるかもしれないですしabとかになるかもしれません。
ネット上で検索していろいろ試してみたのですが惜しい
ところまではいっても完全に正しく動作しませんでした。
(タグやエレメントの中身に反応してしまったり一部分が
置き換えされなかったり<br>タグの後ろが<b></b>のように
なったり)
良いアドバイスください。
よろしくお願いします。

例えば、以下のようなことがしたいのですが可能でしょうか?

変数$bufに複数行の文字列が入っていたとしてこのうち、
タグとエレメント外を対象にしてマッチさせる
(例として以下のような文字列にしたい)

<a href="abcdef">abcdef</a><br>
<b>abc</b>defabcdef<br>
abcdef<b>abcdef</b><br>

↓(タグとエレメント外の文字aを<b>a</b>に置き換える)

<a href="abcdef">abcdef</a><br>
<b>abc</b>def<b>a</b>bcdef<br>
<b>a</b>bcdef<b>abcdef</b><br>

実際にはこのときのマッチの対象となる...続きを読む

Aベストアンサー

No.1のお礼にある
http://www.din.or.jp/~ohzaki/regex.htm
を読んで、
ある程度の条件付きですが、正規表現だけで上手くいく方法を作ってみました。
以下は質問文の文字列で上手くいく例です。

s/((?:\G|<(?:\/[^>]+)|(?:br)>)[^<]*?)(a)/$1<b>\2<\/b>/gi;

条件は以下の通りです。

・3層以上の階層構造を持つ文字列は不可
a<x>b<y>c</y>d</x>e
のdの位置にはマッチしてしまいます。

・要素終了タグが省略されている要素はあらかじめ列挙する必要がある。
例えば、
<(?:\/[^>]+)|(?:br)|(?:img [^>]*)>
は<br>と<img>を空要素とみなし、その後の文字を要素外と判断します。
また、img要素は属性を持つことも出来ます。

ただやはり、正規表現だけでパターンマッチを行うのは、個人的にはお勧めしません。
正規表現では、マークアップによる階層構造を認識することが出来ないからです。

No.1の方の例のように、文字列を頭から走査し、階層構造上の現在の位置を判断してから、変換を行う方法がベターです。

文字列がXMLデータなら、XMLパーサーモジュールを使用する事もできます。
この場合は、データの解析はモジュールが行ってくれますので、変換部分のみを自分で書くだけで済みます。
HTML(SGML)データの場合は、終了タグの省略が可能なので、XMLパーサーでは扱えません。

いずれにせよ、どんな手法であっても、対象の文字列に対してそれ相応の文法チェックを事前に行っておかないと、必ず失敗は起きます。

No.1のお礼にある
http://www.din.or.jp/~ohzaki/regex.htm
を読んで、
ある程度の条件付きですが、正規表現だけで上手くいく方法を作ってみました。
以下は質問文の文字列で上手くいく例です。

s/((?:\G|<(?:\/[^>]+)|(?:br)>)[^<]*?)(a)/$1<b>\2<\/b>/gi;

条件は以下の通りです。

・3層以上の階層構造を持つ文字列は不可
a<x>b<y>c</y>d</x>e
のdの位置にはマッチしてしまいます。

・要素終了タグが省略されている要素はあらかじめ列挙する必要がある。
例えば、
<(?:\/[^>]+)|(?:br)|(?:im...続きを読む

Qマッチに関する正規表現

$hoge = ’
<select name="a">
<option value="A" selected>■</option>
<option value="B">★</option>
<option value="C">▲</option>
</select>

<select name="b">
<option value="A">■</option>
<option value="B">★</option>
<option value="C" selected>▲</option>
</select>
’;



となっている場合、
『selected』が付いているoptionにマッチさせ、
そのvalue値【A】や【C】を$hoge1や$hoge2へ代入したいのですが、正規表現はどのようになるのでしょうか?

$hoge =~ /value="?([^"]+)"? selected/g
$hoge1 = $1;
$hoge2 = $2;

↑これでは、ダメでした。
御教授 お願い致しますm( __ __ )m

$hoge = ’
<select name="a">
<option value="A" selected>■</option>
<option value="B">★</option>
<option value="C">▲</option>
</select>

<select name="b">
<option value="A">■</option>
<option value="B">★</option>
<option value="C" selected>▲</option>
</select>
’;



となっている場合、
『selected』が付いているoptionにマッチさせ、
そのvalue値【A】や【C】を$hoge1や$hoge2へ代入したいのですが、正規表現はどのようになるのでしょうか?

$hoge =~ /v...続きを読む

Aベストアンサー

左辺をリストにするとパターン内の()のパターンに一致した部分のリストが返ります。

$_ = $hoge;
my @hoge = /value="(.+)" selected/g;

for(@hoge){
print $_,"\n";
}

Q|。ってなんですか? 正規表現

正規表現の学習中です。読んでいる本の中に次の式がありました。
 (?<=^|。)[^。]+。
日本語の文章の中から一文を抽出するための正規表現です。

 。以外の文字がダーッと連なった後に。が来る文字列
とのことです。
 [^。]は。以外の文字
 +はそれが1個以上ある
ですから
 [^。]+

 。以外の文字が1個以上ある
という意味です。

その後に。が付きますから、
 [^。]+。
だけで
 。以外の文字がダーッと連なった後に。が来る文字列
ということになります。

では
 (?<=^|。)
の意味は何でしょう。

 (?<=なんたら)
は後方参照を意味しますから、
^|。
のすぐ後に
[^。]+
が続くと言いたいのでしょうか。

だとすると
 ^|。
が問題です。

 ^もしくは。
という意味なら、^は正規表現で記号として使われている文字ですから、
 \^|。
と表現されそうなものです。

それに、。は文末でしか利用されない文字ですから、これに注目して検索を行うというのは理解できますが、^は日本語でなんら特徴を持つ文字ではありません。
 ^もしくは。
という理解は間違いでしょう。

それでは^を記号として考えるとして、その前後を[]で囲んでいないから、この^は文字列の先頭を表すのでしょうか。そうすると件の正規表現は
 先頭の|。のすぐ後から。以外の文字が連なった後に。が来る文字列
という意味になります。日本語の一文を抽出する正規表現という解説にかなり近づいてはいます。

しかし
 |。
とは一体何?

|はorを意味する記号ですが、
 何とか or 。
という意味でしょうか。

でも「何とか」は「何とか」なりに何か文字表現がなされていても良さそうですし、それに
 先頭の「何とか」または。のすぐ後から・・・
という解釈は意味不明。

 |。
はどのように解釈すべきなのでしょうか。

お手数をお掛けします。

正規表現の学習中です。読んでいる本の中に次の式がありました。
 (?<=^|。)[^。]+。
日本語の文章の中から一文を抽出するための正規表現です。

 。以外の文字がダーッと連なった後に。が来る文字列
とのことです。
 [^。]は。以外の文字
 +はそれが1個以上ある
ですから
 [^。]+

 。以外の文字が1個以上ある
という意味です。

その後に。が付きますから、
 [^。]+。
だけで
 。以外の文字がダーッと連なった後に。が来る文字列
ということになります。

では
 (?<=^|。)
...続きを読む

Aベストアンサー

未検証だけど,

^ 先頭(には直前の文がなく句点がない)
| または
。抽出しようとしている文の直前の文の句点
じゃないの?

#^\|。じゃないから…


このカテゴリの人気Q&Aランキング

おすすめ情報