• ベストアンサー

正規表現の 「 * 」

正規表現の 「 * 」は、直前パターンの繰り返しですよね? つまり、a* は a, aa, aaa, aaaa, aaaaa, ..... にマッチするわけですよね? ところで、 echo abbbaaa | sed 's/a*/x/g' のようにしたら a, aaa の部分が x に置き換わって  → xbbbx となることを期待していたのですが、  → xbxbxbx となってしまいました。 なぜでしょうか?

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

  • ベストアンサー
  • -izayoi-
  • ベストアンサー率45% (48/105)
回答No.4

「0個以上の繰り返し」は、通常以下のような場合に使います。  sed 's/#a*#/x/g'  入力文字 → 実行結果  (1) ## → x  (2) #a# → x  (3) #aa# → x  (4) #ab# → #ab#(一致しないので変更無し) ポイント(「1個以上の繰り返し」との違いは)(1)で、「a」の存在が必須ではなく、 その前後の文字列との関係がキーになるような場合に便利なのです。(「1個以上の 繰り返し」だと、(1)は一致しません。) 実際にもっと有用な例を示します。 行末に「#」で始まるコメントが記述されているテキストの、コメント部分だけを削除 するには、以下のようにします。(以下、半角空白1文字を「△」で表現します。)  sed 's/△*#.*$//g' 「△*」は、コメントまでの間に空白があった場合に、その空白も不要なので削除する為 に用います。これを「1個以上の繰り返し」にしてしまうと、コメントまでの間に空白 を含まないステートメントは、コメントが削除できずに残ってしまいます。 例)  if(xxxx)△△△#xxxの判定 → if(xxxx)  if(xxxx)#xxxの判定 → if(xxxx) 「#.*$」は、「#」の後の文字を行末まで全て削除します。「.」(任意の文字)の 「1個以上の繰り返し」にすると、「#」の後ろに文字が無いステートメントは削除でき ずに残ってしまいます。 例)  if(xxxx)△#xxxの判定 → if(xxxx)  if(xxxx)△# → if(xxxx) このように、「*」(0個以上の繰り返し)は本来、他のものと複合して使うことで効果 を発揮します。 ご質問の例のような条件の場合は、「1個以上の繰り返し」を使って下さい。 正規表現は、実際に複雑なパターンをいろいろ試して行くと、その利便性や真髄が解って きます。 プログラミング言語と同様に、「習うより慣れる」類のものかも知れません。

その他の回答 (3)

回答No.3

> aとbの間も何もないので abbb の部分は → xxbxbxb となるべきだと思うのですがどうでしょうか? なるべく長い列をマッチさせようと試みるからです。

回答No.2

> 正規表現の 「 * 」は、直前パターンの繰り返しですよね? 直前パターンの '0個以上の' 繰り返しです

white-tiger
質問者

補足

ありがとうございます。 「ゼロ個」の繰り返し、というのがピンとこないのですが、「何もない文字列」ということでしょうか? bとbの間は何もないので bbb の部分が → bxbxb となるのは分かります。 しかし、aとbの間も何もないので abbb の部分は → xxbxbxb となるべきだと思うのですがどうでしょうか? つまり、 a → x aとbの間 → x b → b bとbの間 → x b → b bとbの間 → x b → b ということですが。

  • -izayoi-
  • ベストアンサー率45% (48/105)
回答No.1

「*」は直前パターンの0個以上の繰り返しを表すので、このような結果になったと思います。 ご希望の結果を得るには、「a」の1個以上の繰り返しを指定します。 sedの正規表現に「+」があれば「a+」を、無い場合は「aa*」と指定してみて下さい。

関連するQ&A