13

AJAX呼び出しは、JSON文字列を含む応答テキストを返します。する必要がある:

  1. JSON文字列を抽出します
  2. それを変更する
  3. 次に、それを再挿入して元の文字列を更新します

手順2と3についてはあまり心配していませんが、手順1の方法がわかりません。正規表現を使用することを考えていましたが、JSONにネストされたオブジェクトを持つ複数のレベルがある可能性があるため、方法がわかりません。または配列。

4

3 に答える 3

17

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

ただし、JSONの最上位要素が常にオブジェクトまたは配列であることがわかっている場合は、次の方法で実行できます。

  • 文字列の最初の開始({または[)と最後の終了(}または])中括弧を見つけます。
  • を使用して、そのテキストブロック(中括弧を含む)を解析してみてくださいJSON.parse()。成功した場合は、終了して解析結果を返します。
  • 前の閉じ中括弧を取り、その文字列を解析してみてください。それが成功した場合、あなたは再び行われます。
  • ブレースがなくなるか、現在のオープニングブレースの前に来るブレースがなくなるまで、これを繰り返します。
  • 手順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/

于 2012-05-13T19:26:50.573 に答える
2

一般にテキストからJSON文字列を抽出することを(私がそうであったように)探している他の人のために(それらが有効でない場合でも)、このGulpプラグイン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ます。

于 2015-07-29T06:44:58.450 に答える
0

JSONがajax応答の一部として返される場合は、ブラウザーのネイティブJSON解析を使用してみませんか(落とし穴に注意してください)。またはjQueryJSON解析

JSONがテキストと完全に混同されている場合、それは実際に設計上の問題を引き起こしますIMHO-変更できる場合は、変更することを強くお勧めします(つまり、応答として単一のJSONオブジェクトを返し、テキストをオブジェクト)。

そうでない場合、RegExの使用は絶対的な悪夢になります。JSONは当然非常に柔軟性があり、正確な解析を保証することは時間がかかるだけでなく、無駄になります。私はおそらく最初/最後にコンテンツマーカーを入れて、最高のものを望んでいます。ただし、検証エラーなどに対して広くオープンになります。

于 2012-05-13T19:38:38.187 に答える