2012-05-13 16 views
9

AJAX呼び出しがJSON文字列を含む応答テキストを返しています。私が行う必要があります。テキストからJSONを抽出します。

  1. JSON文字列を抽出し、私は、ステップ2と3についてあまり心配していないが、私はできる元の文字列に

を更新するために、それを再挿入、その後

  • それを変更手順1を実行する方法を理解していません。正規表現を使用することを考えていましたが、JSONのネストされたオブジェクトや配列が複数のレベルになる可能性はあります。

  • +2

    あなたはここで新しくはありません。何を試しましたか?あなたのレスポンスはどのように見えますか? –

    +0

    また、RegExはおそらくジョブの正しいツールではありません。 –

    +0

    @Truth私の唯一の回避策は、レスポンステキストにJSON文字列の先頭と最後を示すマーカーを入れることです。誇りに思うことも、答えを導くこともありません。 – Christophe

    答えて

    9

    正規表現を使用して、任意のテキストからJSONを抽出することはできません。正規表現は通常not powerful enough to validate JSON(PCREを使用できない限り)であるため、一致することもできません。可能であれば、JSONを検証することもできます。

    あなたはJSONのトップレベルの要素は、常にオブジェクトまたは配列であることがわかっている場合は、次のようなアプローチで行くことができます:

    • 第一の開口部({または[)を検索し、最後にあなたの文字列に括弧(}または])を入れてください。
    • JSON.parse()を使用して、そのテキストブロック(中括弧を含む)を解析してみてください。成功した場合は、解析した結果を終了して返します。
    • 前の中かっこを取り、その文字列を解析してみてください。成功すれば、もう一度やります。
    • 現在の中括弧の前にあるかっこが1つもなくなるまで、これを繰り返します。
    • 手順1の後に最初の中括弧を見つけます。見つからなかった場合は、文字列にJSONオブジェクト/配列が含まれていないため、停止できます。ここ2.

    をステップ

  • 移動は、JSONオブジェクトを抽出し、オブジェクトとその位置を返す関数です。あなたは本当にトップレベルの配列が必要な場合は、あまりにも、拡張する必要があります:

    function extractJSON(str) { 
        var firstOpen, firstClose, candidate; 
        firstOpen = str.indexOf('{', firstOpen + 1); 
        do { 
         firstClose = str.lastIndexOf('}'); 
         console.log('firstOpen: ' + firstOpen, 'firstClose: ' + firstClose); 
         if(firstClose <= firstOpen) { 
          return null; 
         } 
         do { 
          candidate = str.substring(firstOpen, firstClose + 1); 
          console.log('candidate: ' + candidate); 
          try { 
           var res = JSON.parse(candidate); 
           console.log('...found'); 
           return [res, firstOpen, firstClose + 1]; 
          } 
          catch(e) { 
           console.log('...failed'); 
          } 
          firstClose = str.substr(0, firstClose).lastIndexOf('}'); 
         } while(firstClose > firstOpen); 
         firstOpen = str.indexOf('{', firstOpen + 1); 
        } while(firstOpen != -1); 
    } 
    
    var obj = {'foo': 'bar', xxx: '} me[ow]'}; 
    var str = 'blah blah { not {json but here is json: ' + JSON.stringify(obj) + ' and here we have stuff that is } really } not ] json }} at all'; 
    var result = extractJSON(str); 
    console.log('extracted object:', result[0]); 
    console.log('expected object :', obj); 
    console.log('did it work  ?', JSON.stringify(result[0]) == JSON.stringify(obj) ? 'yes!' : 'no'); 
    console.log('surrounding str :', str.substr(0, result[1]) + '<JSON>' + str.substr(result[2])); 
    

    デモ(nodejs環境で実行されますが、あまりにも、ブラウザで動作するはずです):https://paste.aeum.net/show/81/

  • +0

    興味深い...あなたのリンクは、 "はい、完全な正規表現検証が可能です"と言うページを指しています! – Christophe

    +0

    ああ、ちょっと、受け入れられた答えをスクロールしませんでした - でも、よく、PCREはかなり強力です。私はこれらの機能がJavaScriptで利用できるとは思わない。 – ThiefMaster

    0

    JSON場合は、Ajaxレスポンスの一部として返されますが、ブラウザのネイティブJSON解析(gotchasに注意してください)を使用してみませんか?またはjQuery JSON Parsing

    JSONが完全に文字列に変換されている場合は、実際にはデザイン上の問題が発生します。変更することができれば、そのようにすることを強くお勧めします。オブジェクトのプロパティとして)。

    そうでない場合、RegExを使用することは絶対的な悪夢になるでしょう。 JSONは当然非常に柔軟性があり、正確な構文解析が時間を費やすだけでなく、無駄になることを確実にします。私はおそらく開始/終了時にコンテンツマーカーを入れ、最高のものを願っています。しかし、あなたは検証エラーなどに広く目を向けるつもりです。

    +0

    残念ながら私はそれを変更することはできません。レスポンスには、JSONリテラルのパラメータを含むスクリプト全体が含まれています。 – Christophe

    +0

    質問に対するあなたのコメントで、JSON文字列の開始/終了にマーカーを追加したので、私は混乱していますか?どのようにしてレスポンスを変更することができないのですか? –

    +0

    申し訳ありませんが、私は、JSONが実際にスクリプトである "テキスト"と混同されるのを防ぐことができないということです。 – Christophe

    1

    一般的なテキストからJSON文字列を抽出する(私が行ったように)(たとえそれらが有効でないとしても)このGlupプラグインを見てくださいhttps://www.npmjs.com/package/gulp-extract-json-like。JSON文字列のように書式設定されているように見えるすべての文字列を検索します。

    フォルダを作成してパッケージをインストールします。

    mkdir project && cd project 
    npm install gulp gulp-extract-json-like 
    

    ファイル./gulpfile.jsを作成し、その中に以下の内容を置く:

    var gulp = require('gulp'); 
    var extractJsonLike = require('gulp-extract-json-like'); 
    
    gulp.task('default', function() { 
        return gulp.src('file.txt') 
        .pipe(extractJsonLike()) 
        .pipe(gulp.dest('dist')); 
    }); 
    

    は、あなたのテキストが含まれており、次のコマンドを実行します。./file.txtというファイルを作成します。

    gulp 
    

    見つかったJSON文字列は./dist/file.txtになります。

    関連する問題