3

重複の可能性:
一重引用符内の二重引用符をエスケープする正規表現

"すべての二重引用符を\"単一引用符で囲まれた文字列内にあるaに置き換えるには、正規表現 (他の言語はありません!!、perl 構文 REGEX または PCRE 構文 REGEX が最適です) が必要です。これは文字列の例です (ファイルの一部):

var baseUrl = $("#baseurl").html();
var head = '<div id="finishingDiv" style="background-image:url({baseUrl}css/userAd/images/out_main.jpg); background-repeat: repeat-y; ">'+
'<div id="buttonbar" style="width:810px; text-align:right">';

(注意: 「someValueBetween」をペアにする必要はないため、単一引用符で囲まれた 1 つの文字列に奇数の二重引用符が存在する可能性があります。)

上記の最後の行の最終結果は次のようになります。

'<div id=\"buttonbar\" style=\"width:810px; text-align:right\">';

前もって感謝します

***更新: 明確にするために、perl プログラムではなく、正規表現のみが必要です。正規表現は、perl regex 構文または PHP PCRE 構文にすることができます (これは、私が理解している perl regex 構文に非常に近い構文です)。目標は、正規表現をサポートする検索および置換メニュー (Eclipse や PhpEd fe など) で、IDES で正規表現を実行できるようにすることです!!

言い換えれば、"結果として一重引用符で囲まれた文字列ですべてエスケープされていない検索 IDE フィールドに入れる正規表現が必要です。日食の置換フィールドでは、\$1それらをエスケープするために置くことができます。

それらは Regexbuddy または regex コーチで動作するはずなので、テストできます。

少なくともそれが計画です:)


4

3 に答える 3

4

Perl (または PCRE) だけを要求しました。

Ok。

エスケープされていない二重引用符をどこで見つけてもエスケープしたい場合は、次のようにします。

  s{
      (?<! (?<! \\ ) \\{1} )
      (?<! (?<! \\ ) \\{3} )
      (?<! (?<! \\ ) \\{5} )
      (?<! (?<! \\ ) \\{7} )
      (?= " )
  }{\\}xg;

エスケープされていない単一引用符の間のエスケープされていない二重引用符をエスケープしたい場合で、そのような単一引用符のペアが 1 つしかない場合は、次のようにします。

1 while s{

  (?(DEFINE)

    (?<unescaped>
      (?<! (?<! \\ ) \\{1} )
      (?<! (?<! \\ ) \\{3} )
      (?<! (?<! \\ ) \\{5} )
      (?<! (?<! \\ ) \\{7} )
    )

    (?<single_quote> (?&unescaped) ' )
    (?<double_quote> (?&unescaped) " )
    (?<unquoted>     [^'] *?          )

  )

  (?<HEAD>
    (?&single_quote)
    (?&unquoted)
  )

  (?<TAIL>
    (?&double_quote)
    (?&unquoted)
    (?&single_quote)

  )

}<$+{HEAD}\\$+{TAIL}>xg;

しかし、1 行にエスケープされていない一重引用符のペアが複数ある可能性があり、これらのエスケープされていない一重引用符の間にあるエスケープされていない二重引用符のみをエスケープしたい場合は、次のようにします。

sub escape_quote {
  my $_ = shift;
  s{
      (?<! (?<! \\ ) \\{1} )
      (?<! (?<! \\ ) \\{3} )
      (?<! (?<! \\ ) \\{5} )
      (?<! (?<! \\ ) \\{7} )
      (?= " )
  }{\\}xg;

  return $_;
}

s{

  (?(DEFINE)

    (?<unescaped>
      (?<! (?<! \\ ) \\{1} )
      (?<! (?<! \\ ) \\{3} )
      (?<! (?<! \\ ) \\{5} )
      (?<! (?<! \\ ) \\{7} )
    )

    (?<single_quote> (?&unescaped) ' )
    (?<unquoted>     [^'] *?          )

  )

  (?<HEAD> (?&single_quote) )
  (?<TARGET> (?&unquoted) )
  (?<TAIL> (?&single_quote) )

}{
               $+{HEAD}    .
  escape_quote($+{TARGET}) .
               $+{TAIL}

}xeg;

これはすべて、エスケープされていない単一引用符を含む正当なペアのエスケープされていない二重引用符がないことを前提としていることに注意してください。このようなものでさえ、あなたを失望させます:

my $cute = q(') . "stuff" . q(');

ただし、おそらく、適切な解析モジュールを使用する必要があります。

派手で欺瞞に満ちた不適切な SO カラーリングには注意を払わないでください。何らかの理由で、Perl のように Perl を解析できないようです。理由は想像できません。☺</p>

于 2010-11-01T23:26:57.090 に答える
2

あなたの編集によると、特定されていない IDE またはテキスト エディターの検索と置換機能で汎用正規表現を使用する必要があります。それほど単純ではありません。さまざまな言語 (Perl、Java、Python など) には、さまざまな機能セットと構文の癖を備えた独自の正規表現がある傾向があることを認識していると思います。エディタと IDE の間の状況はさらに悪いです。

更新:これを書いてから、Visual Studio は .NET フレーバーの使用に切り替えられ、Notepad++ は Boost ライブラリを採用しました。以下の正規表現は、Visual Studio を除く、私が言及したすべてのエディター/IDE で機能するようになりました。(.NET は所有量指定子をサポートしていませんが、同じ効果に使用できるアトミック グループがあります。)

JEdi​​t と IntelliJ IDEA は Java で書かれており、Java の正規表現を使用していますが、これは非常に優れています。しかし、Visual Studio は優れた .NET フレーバーを使用していません。代わりに、折衷的な機能セットと奇妙な構文を備えた従来のフレーバーを使用します。Apple 開発者が絶賛している Mac エディターの TextMate は、機能豊富な鬼車フレーバーを使用していますが、Notepad++ (無料の Windows エディターであり、多くの良い報道も得ています) は、機能セットが非常に限定されたフレーバーを使用しています。交代もサポート!

そのため、使用しているエディターによっては、比較的単純なタスクでも困難または不可能になる可能性がありますが、実行しようとしているのは非常にトリッキーです。私が思いついた最も単純な正規表現は次のとおりです。

探す: \G((?:(?:\A|')[^']*+')?+[^'"]*+)"([^'"]*+)

交換: $1\\"$2

(これは、すべてのアポストロフィが引用符として使用されていることを前提としています。コメント、二重引用符で囲まれた文字列などに含まれているため、それらのいずれも無視する必要はありません。テキストには、エスケープされた引用符(単一または二重)が既に含まれていません。そしてリストは続きます。)

(前の一致\Gの終わりのアンカー) は不可欠ですが、これは、JavaScript や Python などのより一般的な正規表現フレーバーの一部でさえサポートされていない機能です。所有量指定子 ( , ) は、一致が不可能な場合に正規表現が動かなくなるのを防ぎます。PCRE、鬼車、Perl 5.10+、および Java で利用できます。.NET にはそれらがありませんが、やや扱いにくい代替のアトミック グループがあります。*+?+

ジェネリック正規表現のアプローチは忘れて、必要な機能を備えたツール セットで標準化することをお勧めします。一般的な用途では、JGSoft ファミリのツール (EditPad Pro、PowerGrep、および RegexBuddy) に勝るものはないと思います。機能とパフォーマンスの両方において、JGSoft の正規表現のフレーバーは他のどの製品よりも優れています。欠けているのは、再帰マッチングと埋め込みコード機能だけです。

psコメントでEclipseについて言及しました。私はそれをインストールしていませんが、Java の正規表現フレーバー (または構文が実質的に Java のものと同じである ICU フレーバー) を使用していると予想されるため、上記の正規表現はそこで動作するはずです。

于 2010-11-02T10:26:31.140 に答える
0

(あなたの例のように)行ごとに一重引用符で囲まれた文字列が1つしかない限り、これは機能するはずです(sed構文):

s|'\([^'"]*\)"\([^']*\)'|'\1\"\2'|g
于 2010-11-01T21:25:54.340 に答える