Из-за способа вывода моих серверных скриптов я получаю несколько объектов JSON. {jsonhere}{jsonhere1}{jsonhere2}{jsonhere3} etc.. Они ничем не разделены. Если бы я сделал }{ на основе разделения, я бы потерял эти скобки. Итак, есть ли внешний цикл, который я могу надеть поверх обычного цикла $.each, чтобы заставить эту работу работать?
Спасибо,
Лед

это не JSON.
jQuery интерпретирует JSON лениво, вызывая eval () и надеясь, что там нет «настоящего» кода; поэтому он этого не примет. (я думаю, вы это уже знаете).
кажется, ваш единственный выход - рассматривать его как текстовую строку и использовать регулярные выражения для извлечения данных.
Это смешно, и вы заслуживаете нескольких часов тяжелой работы по программированию, чтобы преподать вам урок.
Привет, Адам! ха-ха - мне приходилось использовать их гораздо чаще, чтобы понять, как избегать их везде, где это возможно ;-)
Если вы не можете гарантировать, что какие-либо строки в данных не будут содержать "} {", вы даже не сможете безопасно разделить их, не проанализировав JSON, по крайней мере, для отслеживания того, находитесь ли вы в строке или нет. Например, если вы просто разделите это:
{"foo": "}{", "bar": 42}
вокруг "} {" вы получите два недопустимых объекта JSON вместо одного.
Если вы знаете, что этого никогда не произойдет, вы можете разделить фигурные скобки и добавить "}" к каждому элементу, кроме последнего, и добавить "{" к последнему элементу. Я бы сделал это только в том случае, если бы не было абсолютно другого пути, потому что В самом деле хрупкий.
Грубый алгоритм:
Define a stack
Define an array
LOOP on each character in the string
IF the top item of the stack is a single or double quote THEN
LOOP through each character until you find a matching single or double quote, then pop it from the stack.
ELSE
IF "{", push onto the stack
IF "}" THEN
pop a "{" from the stack if it is on top
IF the stack is empty THEN //we just finished a full json object
Throw this json object into an array for later consumption
END IF
END IF
IF single-quote, push onto the stack
IF double-quote, push onto the stack
END IF
END LOOP
Мне удалось сколотить рабочий пример! Сохраните следующий текст как HTML-страницу. Кажется, он хорошо работает в IE7 и FF3. Сообщите мне, если у вас возникнут проблемы.
(Я использовал jquery, но в этом нет необходимости.)
<html>
<head>
<script type = "text/javascript" src = "jquery-1.2.6.js"></script>
<script type = "text/javascript">
function handleClick() {
var jsonStrs = parse();
var jsonObjs = [];
for(var j=0;j<jsonStrs.length;j++) jsonObjs.push( parseJSON(jsonStrs[j]) );
//jsonObjs now contains an array of json objects
document.getElementById('log').innerHTML = '';
displayResults(jsonObjs);
}
function displayResults(jsonObjs) {
for(var k=0; k<jsonObjs.length; k++) {
ShowObjProperties(jsonObjs[k]);
}
}
function ShowObjProperties(obj) {
var property, propCollection = "";
for(property in obj) {
propCollection += (property + ": " + obj[property] + "<br>");
}
log(propCollection);
}
function parseJSON(str) {
var x_result = null;
eval('x_result = ' + str);
return x_result;
}
function parse() {
//Setup
var out = $('#output');
var rawinput = $('#inputtext').val();
var input = rawinput.split('');
var stack = [];
stack.top = function() {
if (this.length == 0) return null;
return this[this.length-1];
}
var jsonStrs = [];
//Main Loop
var ch = '';
var top = '';
var cursor = 0;
var i = 0;
while (i<input.length) {
//Current Character
ch = input[i];
top = stack.top();
if (top == "'" || top == '"') { //Ignore the rest of the string
//You can add validation for possible unsafe javascript inside a string, here.
ch = input[++i];
while(ch != top) {
i++;
if (i>=input.length) {
alert('malformed string');
break;
}
ch = input[i];
}
stack.pop();
} else {
//You can add validation for unsafe javascript here.
if (ch == ' ') {
i++;
continue; // Ignore spaces
}
if (ch == "{" || ch == "'" || ch == '"') stack.push(ch);
if (ch == "}") {
if (top= = "{") {
stack.pop();
} else {
alert('malformed string');
break;
}
if (stack.length == 0) {
var str = rawinput.substring(cursor, i+1)
jsonStrs.push(str);
cursor = i+1;
}
}
}
i++;
}
return jsonStrs;
}
function log(msg) {
document.getElementById('log').innerHTML += msg + '<br>';
}
</script>
</head>
<body>
<textarea id = "inputtext" rows = "5" cols = "40" style = "overflow:auto">{foo:'bar'}</textarea><br>
<button id = "btnParse" onclick = "handleClick();">Parse!</button><br /><br />
<div id = "output">
</div>
<b>Results:</b>
<div id = "log"></div>
</body>
</html>
Это не JSON, на стороне клиента просто исправьте свой код JSON, и вы можете безопасно его «оценить».
var jsonWrong = '{a:1}{a:2}{a:3}';
var jsonRight = jsonWrong.replace('}{', '},{');
var json = eval('('+jsonRight+')');
Это не удается в следующем примере: {foo: 'sometext', bar: 'more} {text'} {moo: 'another string'} Потому что это будет вставлять запятую в строку.
Вы сказали в вопросе, что пытались разделиться на} {, поэтому я предположил, что у вас нет} {в ваших ценностях ...
Следующее будет правильным ответом JSON:
[
{JSON},
{JSON},
{JSON},
{JSON}
]
Поскольку ваш JSON имеет неправильный формат, просто исправьте его на стороне сервера. Следующий код немного короче того, что предлагал EndangeredMassa, и в нем не добавляется запятая между фигурными скобками, заключенными в кавычки. Я не настолько хорош в RegEx, чтобы понять это с помощью одного .replace ().
var string = "{\"key\":\"val}{ue\"}{'key':'val}{ue'}{ \"asdf\" : 500 }";
var result = string.match(/('.*?')|(".*?")|(\d+)|({)|(:)|(})/g);
var newstring = "";
for (var i in result) {
var next = parseInt(i) + 1;
if (next <= result.length) {
if (result[i] == "}" && result[next] == "{") {
newstring += "},";
}
else {
newstring += result[i];
}
}
}
Для перебора объектов JSON используйте следующее:
$.each(eval(newstring), function() {
//code that uses the JSON values
alert(this.value1);
alert(this.value2);
});
Ой! Думаю, тогда я буду кодировать серверную часть - я отказываюсь использовать регулярные выражения