2

エスケープされた一重引用符を含む、2 つの一重引用符の間の ANY 値のすべての出現を置き換えようとしています。以下は、エスケープされた一重引用符が見つかった場合を除いて、非常にうまく機能します。これは理にかなっていますが、それを回避する方法はありますか。一重引用符の間のすべての文字を置き換えたい。

$ echo "'blah\'blah'" | perl -pe s/"'"[^"'"]*"'"/stuff/g
stuffblah'

私はただ見たい:

stuff
4

2 に答える 2

0

引用符内で、次のトークンを許可したい

  1. すべての引用符以外の文字[^']または
  2. または\'としてエンコードされたすべてのエスケープされた引用符\\'
  3. \\としてエンコードされたすべてのエスケープされたバックスラッシュ\\\\考えられるすべてのデータを表すには、この追加のルールが必要です。

正規表現のorはパイプ文字|で示され、これらの可能なトークンを括弧で囲み、反復のためにグループ化します。

( \\\\ | \\' | [^'] )*

または、エスケープできるものをより明確に示します。

( \\[\\'] | [^'] )*

これを引用符で囲み、グループ化括弧を保存しないようにします (変数$1などを作成する必要はありません)。

s {' (?: \\[\\'] | [^'] )* '}
  {stuff}gx

/x読みやすくするために、修飾子を使用して非意味的な空白を含めることに注意してください。

編集:Perlワンライナー

すべてのワンライナーは の下でテストされましbashた。他のシェルは、他の引用の恐怖を表示します。次の行では、エスケープされていない正規表現が提供されます。

このワンライナーは、指定されているように一重引用符に一致します。

perl -pe"s/'(?:\\\\[\\\\']|[^'])*'/stuff/g"
         s/'(?:\\  [\\']  |[^'])*'/stuff/gx

バックスラッシュを 2 倍にするのは、シェルのエスケープに対応するためです。

このワンライナーは二重引用符に一致します。

perl -pe"s/\"(?:\\\\[\\\\\"]|[^\"])*\"/stuff/g"
         s/ "(?:\\  [\\"]   |[^"] )* "/stuff/gx
于 2012-09-21T01:46:28.600 に答える
0

問題は、2 つの blah の間に一重引用符が 1 つしかないため、最初の 'blah' が置き換えられると、2 番目の blah' が一重引用符で囲まれなくなることです。エスケープされた単一引用符を許可する場合は、次のようにします。

 s/\\?'[^']*'/stuff/g
于 2012-09-21T01:46:35.490 に答える