1

私はいくつかの文法ファイルを解析するためのJavascriptコードを書いています、それはかなりのコードですが、ここに関連情報を投稿します。文字列内に保持されている重複行を照合するために、JavascriptRegexpを使用しています。文字列には、たとえば、次のものが含まれます(文字列名が行であると想定します)。

    もしも
    そうしないと
    ;
    印刷
    {{
    }
    test1
    test1
    =
    +
    -
    *
    /
    ((
    )。
    num
    ストリング
    コメント
    id
    test2
    test2

何が起こるかは、「test1」と「test2」で見つかった一致です。次に、重複を削除して、test1とtest2のインスタンスを1つ残します。何が起こっているのかはまったく一致しません。私は正規表現に自信がありますが、javascriptが予期しないことをしている可能性があります。上記の文字列で作業を行うコードは次のとおりです。

var rex = new RegExp("(.*)(\r?\n\1)+","g");
var re = '/(.*)(\r?\n\1)+/g';

rex.lastIndex = 0;


var m = rex.exec(lines);
    if (m) {
        alert("Found Duplicate");
        var linenum = lines.search(re);            //Get line number of error
        alert("Error: Symbol Defined twice\n");
        alert("Error occured on line: " + linenum);
        lines = lines.replace(rex,"");         //Gets rid of the duplicate
    }

if(m)ステートメントには決して入りません。したがって、一致するものは見つかりません。ここで正規表現をテストしました:http ://regexpal.com/ コードで正規表現と提供されたサンプルテキストを使用します。うまくマッチしているので、ちょっと戸惑います。誰かが助けることができれば、それは素晴らしいことです。

ありがとうございました。

編集:追加するのを忘れました、私はこれをFirefoxでテストしています、そしてそれはFirefoxでのみ機能する必要があります。それが重要かどうかわからない。

4

2 に答える 2

0

最初のエラー: \JS 文字列の もエスケープ文字です。

var rex = new RegExp("(.*)(\r?\n\1)+","g");

書かれるべき

var rex = new RegExp("(.*)(\\r?\\n\\1)+","g");
// or, shorter:
var rex = /(.*)(\r?\n\1)+/g;

あなたがそれを機能させたい場合。コンストラクターの場合RegExp、パターンを文字列としてコンストラクター関数に渡します。\これは、パターンで発生する各バックスラッシュをエスケープする必要があることを意味します。正規表現リテラルを使用する場合、それらは文字列ではないため、エスケープする必要はありませんが、正規表現パターンで「通常の」プロパティを保持します。

2番目のエラー、あなたの式

var re = '/(.*)(\r?\n\1)+/g';

間違っている。ここで行っているのは、文字列リテラルを変数に代入することです。次のように記述する必要がある正規表現リテラルを割り当てるつもりだったと思います。

var re = /(.*)(\r?\n\1)+/g;

3 番目のエラー: 最後の行

lines = lines.replace(rex,"");         //Gets rid of the duplicate

すべての重複行の両方のインスタンスを削除します! 各複製の最初のインスタンスを保持したい場合は、使用する必要があります

lines = lines.replace(rex, "$1");

最後に、この方法では 2 つの連続した同一行しか検出されません。それはあなたが望むものですか、それとも重複がどこにあっても検出する必要がありますか?

于 2013-01-22T14:58:49.397 に答える
0
var str = 'if\nelse\n;\nprint\n{\n}\ntest1\ntest1\n=\n+\n-\n*\n/\n(\n)\nnum\nstring\ncomment\nid\ntest2\ntest2\ntest2\ntest2\ntest2';
console.log(str);
str = str.replace(/\r\n?/g,'');
// I prefer replacing all the newline characters with \n's here
str = str.replace(/(^|\n)([^\n]*)(\n\2)+/g,function(m0,m1,m2,m3,ind) {
    var line = str.substr(0,ind).split(/\n/).length + 1;
    var msg = '[Found duplicate]';
    msg += '\nFollowing symbol defined more than once';
    msg += '\n\tsymbol: ' + m2;
    msg += '\n\ton line ' + line;
    console.log(msg);
    return m1 + m2;
});
console.log(str);

それ以外の場合は、最初の行をスキップしてパターンを次のように変更できます

/(^|\r\n?|\n)([^\r\n]*)((?:\r\n?|\n)\2)+/g

[^\n]*複数の空行もキャッチすることに注意してください。空でない行に一致する (および置換する) ことを確認したい場合は、 を使用することをお勧めします[^\n]+

[編集]

レコードの場合、それぞれが各オブジェクトをm表し、一致全体、は最初のサブグループ ( )、は 2 番目のサブグループ ( )、は最後のサブグループ ( ) です。代わりに使用することもできましたが、これらは短くなっています。argumentsm0m1(^|\n)m2([^\n]*)m3(\n\2)arguments[n]

戻り値と同様に、Javascript で使用される正規表現フレーバーには後読みがないため、このパターンは (最初の行でない限り) 前にある可能性のある改行をキャッチしているため、一致したものと前にある改行があればそれを返す必要があります。m2そのため、戻るだけではいけません。

于 2013-01-22T14:39:56.937 に答える