2

私は別の Javascript 正規表現の難問を抱えています... (これが少し長文である場合はお詫びします - 説明するのは難しいです!)

文字列をポップアップ ウィンドウに送信するスクリプトがあります (すべての文字は送信時にエンコードされるため、すべてのバックスラッシュが保持されます)。ポップアップには、いくつかのテキスト入力ボックスと、すべての入力ボックスの内容を表示する「概要」スパンがあり、キーアップが検出されるたびに更新されます。次に、ユーザーが終了したら、ボタンをクリックして、更新された要約文字列をオープナーに送り返します。

要件は、バックスラッシュが次の文字の前に自動的に追加されることです: \ / }。したがって、ユーザーが自分でこれを行う必要はありません。現在、入力ボックスのバックスラッシュを取り除くコードがありますが、要約では必要に応じてバックスラッシュが追加されています。

例えば。この文字列がポップアップに送信された場合:foobar\\batz\/hi 要約では次のfoobar\\batz\/hiようになり、入力ボックスでは次のようになります: foobar\batz/hi。次に、入力ボックスで次のように文字列を編集すると: foobar\batz/hiya、要約では次のようになります: foobar\\batz\/hiya。これまでのところは順調ですが、入力ボックスにこれを入力しようとすると: foobar\\batz/hiya、要約では次のようになります: foobar\\\batz\/hiya。次のようになります。foobar\\\\batz\/hiya

これは既存のコード (すべての 'kepup' で実行される) によるものです。\ / or }基本的に、文字列を確認し、まだ存在しない場合はバックスラッシュを追加するには、正規表現が必要です。これには、既存のバックスラッシュをチェックするための否定後読みが必要です (ただし、javascript は否定後読みを実行できません)。最初に (カスタム関数を使用して) 文字列を反転し、否定的な先読みを行ってから、次のように文字列を再び反転することで、これをクラックしたと思いました。

var thisBoxVal = $(this).val();
thisBoxVal = reverseStr(thisBoxVal);
thisBoxVal = thisBoxVal.replace(/(\}|\/|\\(?!\\))/g,"$1\\");
thisBoxVal = reverseStr(thisBoxVal);

しかし、今では問題がどこにあるのかがわかります。2 つのバックスラッシュの最初 (または反転されているため 2 つ目) に遭遇すると、余分なバックスラッシュが追加されます。しかし、2 番目のバックスラッシュにはこの最初のバックスラッシュが既にあるため、追加されません。

また、文字列が反転されるたびにメモリの割り当てについても懸念があります。これは、javascript 文字列が不変であることを学んだためです。文字列が反転されるたびに、より多くのメモリが割り当てられるという不幸な影響があると思います。キーストロークごとにこれを行うと (入力ボックスが変更されるたびに要約行を更新するためにこれを行う必要があるため)、いくつかの問題が発生する可能性があります (...?)。

これを行う他の方法はありますか?できれば、正規表現だけで、元に戻すことはありません...

要約すると、要件は、これらの文字のいずれかを文字列で検索し、\ / }それらの前に「エスケープ」バックスラッシュを追加する正規表現置換を作成することです (エスケープ バックスラッシュがまだ存在しない場合)。したがって、複数のバックスラッシュが連続して発生したときに、それぞれをエスケープするためのインテリジェンスが必要です (実際の入力ボックスを更新するのではなく、要約を更新するために使用する変数を更新していることに注意してください)。

正規表現マスターの助けが必要です!

4

3 に答える 3

2

文字、数字、スペース、またはバックスラッシュ以外のものはすべてエスケープできます。

string=string.replace(/([^\w \\])/g,'\\$1')
于 2011-03-02T13:21:16.740 に答える
1

以下はそれを解決するはずです:

thisBoxVal = thisBoxVal.replace/((\}|\/(?!\\))|\\)/g,"$1\\");

しかし、要件は奇妙に思えます。なぜ\\に変換する必要があります\\\\が、\{に変換し\{ます。これは、文字列foo\\{barが要約にある場合はfoo\{bar入力ボックスにあり、それを再度保存するとfoo\{bar要約になることも意味します。それはエラーのように聞こえます。私があなただったら、否定的な先読みを完全にやめます..

于 2011-03-02T12:48:39.957 に答える
1

エスケープする文字の前にバックスラッシュが偶数個あるかどうかを確認することで、既存のバックスラッシュ エスケープを確認できます。この場合、バックスラッシュを追加する必要があります。

thisBoxVal = thisBoxVal.replace(/(^|[^\\])((?:\\{2})*)(\\(?=[^\\/}]|$)|[/}])/g, '$1$2\\$3');

正規表現は次のように分解されます。

  • (^|[^\\]): エスケープの前に、エスケープではないもの (文字列の開始または \ 以外) に一致します。
  • ((?:\\{2})*): 偶数個のエスケープ文字。それぞれのペアで、最初のものは 2 番目のものをエスケープするので、これらには触れたくありません。
  • (\\(?=[^\\/}]|$)|[/}]): エスケープする文字:
    • \\(?=[^\\/}]|$): バックスラッシュの後にエスケープできない何かが続きます。これは、エスケープできない文字 ( [^\\/}]、そうでない場合、このバックスラッシュ自体が後続の文字をエスケープすることになります) または文字列の末尾です。
    • [/}]: バックスラッシュ以外のエスケープ可能な文字。

サンプル文字列:

thisBoxVal = "sl0: \\;  sl1: /;  sl2: \\\\\\;  nosl0: \\\\;  nosl1: \\{;  sl3: \\";

印刷値:"sl0: \; sl1: /; sl2: \\\; nosl0: \\; nosl1: \{; sl3: \"
の結果replace:"sl0: \\; sl1: \/; sl2: \\\\; nosl0: \\; nosl1: \{; sl3: \\"

于 2011-03-02T13:09:25.617 に答える