2012-11-29 14 views
7

私は、ユーザーが正規表現を指定できるようにするアプリを書いています。もちろん、ユーザーは間違いを犯すので、解析できない正規表現を処理する方法が必要であり、ユーザーに問題の修正方法に関する実用的な助言を与える必要があります。正規表現JavaScriptの例外を解析する

私が抱えている問題は、new RegExp("something awful")によってスローされた例外はregex n00bsには役に立ちませんし、ブラウザごとに異なるメッセージがあることです。たとえば、次のように考えると

try{ 
    new RegExp("(pie"); 
}catch(e){ 
    console.log(e.message); 
} 
  • Firefoxが "終端されていないの括弧" をスローします。
  • Safariが「不足している)」
  • クローム「終了していませんグループ」

をスローし、それらのメッセージ文字列は、ユーザ言語ローカライズされている、または、彼らは時間をかけて漂流してきたという場合、それは私は驚かないだろうがスローされますこれは、例外.messageで解ける狂った結び目になります。

私の目標は、例外をキャッチし、それが本当に何であるか把握し、初心者にやさしいメッセージを表示することです。 (そして最終的には、この例では比類のない括弧を強調表示します。)

私は使用すべき他の例外識別子がありますか?これらを区別するより良い方法はありますか?そのすべてに失敗して、誰もが最も人気のあるいくつかのブラウザでこれらの文字列が何であるかを収集しましたか?

+1

普段の正規表現のオンラインテストページで何が起きているのか見てみましょう – mplungjan

+1

正規表現 '(abcd) 'に中かっこが少なすぎるのか、あまりにも多すぎるのでしょうか? –

+0

そして、ここでは、可能性の高いメッセージを得るためのトリックです。有効であるが本当に複雑な正規表現をいくつか含むスクリプトを書く。 JavaScriptで利用可能なすべての正規表現機能を実際に使用し、悪用します。それらを入れ子にし、もちろんすべてを入れます。その後、それらの中のいくつかの文字をランダムに削除、追加または変更し、それらをコンパイルしようとします。そしてあなたが得たすべてのエラーメッセージ(それを引き起こした正規表現と共に)を保存してください。ランダム化されているため、多くの失敗事例を試すことができます。自動化することで、重複を心配する必要はありません。 –

答えて

3

アイデア:実行時にすべてを理解してください。例えば。

var tellMeWhatIDidWrong = (function() { 

    var tests = { 
     '(': 'You did not close your group... duh!', 
     ')': 'You seem to have an unmatched parenthesis.', 
     '*': 'That token is illegal in that position' 
    }; 

    var errors = {}; 

    for (var i in tests) { 
     try { RegExp(i); } catch(e) { 
      errors[String(e).split(':').pop()] = tests[i]; 
     } 
    } 


    return function(regexStr) { 
     try { RegExp(regexStr); } catch(e) { 
      e = String(e).split(':').pop(); 
      if (e in errors) { 
       return errors[e]; 
      } 
      return 'Unknown error'; 
     } 
     return 'Nothing -- it is fine!'; 
    }; 

}()); 

tellMeWhatIDidWrong('(abc?'); // -> "You did not close your group... duh!" 

もちろん、これはブラウザの組み込みエラー報告が十分に具体的である場合にのみ有効です。それらの多くは吸う。例えば。 Operaはこの問題に関してはまったくヒントを得ていないので、上記はうまく動作せず、Operaのネイティブエラーメッセージに依存している他のソリューションもありません。

私はアプリのNode.jsを実行すると、正規表現パーサーを作成するために、素敵なV8のエラーメッセージ:)

+0

これは本当に巧妙で、オペラを見てくれてありがとう(試しても私のリストにはなかった)。このアプリケーションには既にサーバー側のNode.jsコンポーネントがありますが、クライアントの忠告ではなく、ラウンドトリップを待ってすぐにサーバーから優れたアドバイスを得るのが理想的かもしれません。 –

1

使用PEG.jsまたはJISONを得るためにオフの正規表現を送信することをお勧め。特定の一貫したエラーを得ることができます。

このファイルには、正規表現のYACC文法があります。http://swtch.com/usr/local/plan9/src/cmd/grep/grep.y; JISONで使用するのは難しくありません。

A PERL正規表現のためのBNF文法:私のコメントから次のhttp://www.cs.sfu.ca/~cameron/Teaching/384/99-3/regexp-plg.html

1

、私は一緒に「収穫」に小さなスクリプト可能性のあるエラーメッセージとそれらの原因となるパターンをハッキングしてきました。

JSFiddle

(のみ、は、私は正規表現の例外オブジェクトが他のブラウザに同じ構造を持っていることを望みますChromeで試してみました)という考えはこれです:あなたは、できるだけ多くの正規表現の機能を使用して作業した正規表現を持っています。その後、ランダムに突然変異させ(文字の追加、削除、または取り替え)、コンパイルしようとします。これを数千回行うことができ、すべてのエラーメッセージを収集することができます。うまくいけばチャンスは、私たちの誰よりも、起こり得る不正なパターンを思いつくことがより良いです。

は、あなたは間違いなくはJavaScriptが提供するすべて正規表現の機能が含まれるように、ベース・パターンを改善し、交換用のテーブル内のすべてののメタ文字を含める必要があります。しかし、そうでない場合、私は一貫して6つの可能性のあるエラーメッセージを取得するように見える:

Unterminated group 
Invalid group  
Nothing to repeat 
Unmatched ')' 
Unterminated character class 
\ at end of pattern 

は、エラーの原因となったパターンを分析し、別のブラウザでこのスクリプトを実行してみてください、そしてそこから、あなたのツールを記述することができるはずです。

EDIT:

さて、私は、彼らは例外オブジェクト内のどこかに実際のメッセージが格納されるため、これは、箱から出して他のブラウザでは動作しません恐れて。しかし、あなたの質問から判断すると、すでにブラウザごとにメッセージを取得する場所がわかっているようですので、変更する必要はありません。