2009-07-10 3 views
3

JSコードのチャンクをマッチさせ、Javaを使用して特定のキーワードを含む文字列リテラルを抽出しようとしています。へJavaを使用してJavascriptの文字列リテラルと特定のキーワードを一致させる正規表現

 
(["']) 
(?:\\?+.)*? 
\1 

これを行うには、私自身の正規表現を思い付くしようとした後、私は(Javaでパターンを構築するときにPattern.COMMENTSを使用)この一般化文字列リテラルのマッチング正規表現を修正することになりました

 
(["']) 
(?:\\?+.)*? 
keyword 
(?:\\?+.)*? 
\1 

次のテストケース:

var v1 = "test"; 
var v2 = "testkeyword"; 
var v3 = "test"; var v4 = "testkeyword"; 

正規表現は正しくDだけではなく、「testkeywordを」マッチングのoesn'tマッチライン1と正しくライン2

と一致した。しかし、3行目では、それは間違っているチャンク

"test"; var v4 = "testkeyword" 

と一致する - 正規表現は、最初に一致しました二重引用符で終わり、2行目の二重引用符で終わらず、行末までずっと進んでいます。

これを修正する方法はありますか?

PS:Regexpは、文字列リテラル(一般化されたマッチャーが既に行ったもの)の中でエスケープされた一重引用符文字と二重引用符文字を正しく処理しなければならないことに注意してください。多くの改正後

答えて

3

どのようにこの変更について:あなたは2を記述する必要が

(?: 
    " 
    (?:\\"|[^"\r\n])* 
    keyword 
    (?:\\"|[^"\r\n])* 
    " 
| 
    ' 
    (?:\\'|[^'\r\n])* 
    keyword 
    (?:\\'|[^'\r\n])* 
    ' 
) 
+0

パーフェクト!必要に応じて動作します! – niktech

1

(私はこれが私の最終的な答えであると信じて、ホーム:)で視聴者を編集履歴を参照してください。

(?: 
    " 
    (?:\\?+"|[^"])* 
    keyword 
    (?:\\?+"|[^"])* 
    " 
| 
    ' 
    (?:\\?+'|[^'])* 
    keyword 
    (?:\\?+'|[^'])* 
    ' 
) 
+0

私はテストしますが、テストケース3は2つの文字列リテラルとして適切に一致します。ここで元の正規表現がhttp://blog.stevenlevithan.com/archives/match-quoted-stringから来たところです – niktech

+0

おっと、そうです。ええ、それは非貪欲な振る舞いに依存しています。あなたはキーワードに固執しているので、同じ方法を使うことはできません。編集中... – chaos

+0

それはうまくいくはずですが、私の場合の問題は偽陽性になります。特殊キーワードを持つ文字列リテラルの確率は約1%です。そして、毎回何百行ものファイルを処理する必要があります。誰も特別なキーワードのリテラルを処理する前にそれを事前にスクリーニングする方法を考え出すことができない場合、私はあなたの解決策につきます。 – niktech

0

正規表現に文字列を開いたことを覚えさせる方法がないので、一重引用符または二重引用符で囲まれた文字列のパターン。次に、あなたは|または一緒にすることができます。

0

実際の文字列リテラルを取得するには、Rhino-JSのJavaコードを使用することを検討してください。

または、regexを使用する場合は、リテラル全体に対して1つの検索を、次にリテラルに 'キーワード'が含まれている場合はネストされたテストを考慮してください。

私はTimの構築がうまくいくと思いますが、すべての状況でそれに賭けてはいけません。見つからないリテラルを扱わなければならないと、正規表現は扱いにくくなるでしょうあなたのテストによってひそかに)。たとえば:

var v5 = "test\x6b\u0065yword" 
任意の溶液から分離

、対話的に正規表現を操作するための私の秘密兵器は、そのような多くのユーティリティとは異なり、Javaアプレットをサポートしているすべてのブラウザで動作Regex Powertoyと呼ばれる私が作ったツールです。非引用符、バックスラッシュと

 
string-literal ::= quote text quote 

text ::= character text 
     | character 

character ::= non-quote 
      | backslash quote 

を、とされて端子を引用:

+0

上記のテストケースは私の状況には当てはまりません。私は、 'キーワード'はASCIIのように表示されることが保証されています。 2つのテスト(文字列リテラルの最初のテスト、次にキーワードの存在のテスト)は、キーワードを持つリテラルの確率が約1%であるため、私のケースでは多くの偽陽性を生成します。 – niktech

0

リテラル文字列を構築するための文法は大体次のようになります。

コンテキストがない場合(つまり、すべてのルールの左側が常に1つの非終端です)、すべてのルールの右側が常に空、端末、または端末のいずれかに続く場合非末端によって。

上記の最初のルールにはターミナルがあり、そのあとにターミナルが続く非終端記号が続くことがわかります。これは規則的な文法ではありません。

正規表現は、通常の言語(正規の文法で構築できる言語)を解析できる式です。正規表現で非正規言語を解析することはできません。

適切な正規表現が見つからないことは、適切な正規表現が存在しないことに起因します。あなたは明らかに正しいコードに到達することはありません。

上記のルールの行に沿って簡単なパーサーを書く方がはるかに簡単です。 にはという文字列のリテラルがであるため、という正規表現が使用されています。の後に簡単な正規表現でを検索すると、そのテキストを抽出できます。

+0

興味深い観察。ティムの解を破るテストケースがあるのですか?それは私のテストケースのすべてを握っているようです。 – niktech

関連する問題