21.06.2019, 09:11
|
Новичок на форуме
|
|
Регистрация: 19.06.2019
Сообщений: 8
|
|
Сообщение от Malleys
|
Почему бы не использовать XML?
|
Потому что приходится работать с тем, что генерирует драйвер устройства. Программиста, написавшего драйвер, по ряду причин достать и заставить переписать STDOUT на XML или JSON намного сложнее.
Сообщение от Alexandroppolus
|
Немного пофиксил, на этот раз вроде всё как надо
|
Спасибо, на такой вариант, с парсингом параметров непосредственно при поиске тегов, несколько затрудняет последующую обработку нестандартных параметров (которые без =значение). Сейчас у меня получается делать это последовательно.
Конкретный пример:
<value name='name<">1' value="value1">
<value name='name2' value = "еще <одно> значение">
<block name="name3" property="tagret" clear>
"текст"
Этот тег не обрабатывается и остается в тексте:
<левый тег парсить="не нужно">
А вот этот тег нужно вырезать из содержимого
и обработать с другими аналогичными:
<value name='name3' clear value="value3">
</block>
<text name="text1" property="target">
а это незакрытый тег, содержимое берется до следующего
такого же или до конца. Левый тег остается в тексте.
<левый тег парсить="не нужно">
<text clear name="text2" property="target">
второй текстовый блок, читается до конца.
<block name="inner block" property="tagret">
А этот текстовый блок тоже вырезается из содержимого
и парсится отдельно.
</block>
Получается как-то так. Не сомневаюсь, что решение далеко от оптимального, но вроде бы работает. По крайней мере пока, с теми примерами вывода, которые я смог получить.
var string = xmlHttp.responseText.replace(/[\r\n]/g, '');
var value = new Array(), block = new Array(), text = new Array();
string = string.replace(/<\s*value(\s+(?:"[^"]*"|'[^']*'|[^>"'])*)?>/gi, function(a,b) {
var obj = PropParse(b);
value.push(obj);
return '';
});
var reg = /<\s*block(\s+(?:"[^"]*"|'[^']*'|[^>"'])*)?>/i;
while (reg.test(string)) {
var pos1 = string.match(reg);
var pos2 = string.match(/<\s*\/\s*block\s*>/i);
var obj = PropParse(pos1[1]);
obj.innerValue = string.substring(pos1.index+pos1[0].length, pos2.index);
string = string.substr(0, pos1.index) + string.substr(pos2.index+pos2[0].length);
block.push(obj);
}
var res = string.split(/<\s*text\s+/i);
for (var i = 0; i < res.length; i++) {
res[i].replace(/^\s*((?:"[^"]*"|'[^']*'|[^>"'])*)>(.*)$/, function(a,b,c) {
var obj = PropParse(b);
obj.innerValue = c;
if (!obj.clear) obj.clear = false;
text.push(obj);
});
}
function PropParse(str) {
var obj = new Object();
var val = str.replace(/\s*([\w-]+)\s*[=:]\s*("[^"]*"|'[^']*'|[\w-]+)\s*/g, function(a,b,c) {
obj[b.trim()] = c.trim().replace(/(^["']|["']$)/g, '');
return '';
});
val = val.replace(/[^\s\w-]/, '');
var left = val.split(/\s/);
for (var i = 0; i < left.length; i++) {
obj[left[i].trim()] = true;
}
return obj;
}
|
|
21.06.2019, 13:04
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
вот примерно так (см. в консоль)
https://jsfiddle.net/n3a1ofb0/
здесь есть всё, кроме экранирования кавычек в атрибутах, о чем были регулярки с \\\\ на предыдущей странице. Если надо, можно это добавить
|
|
21.06.2019, 13:43
|
Новичок на форуме
|
|
Регистрация: 19.06.2019
Сообщений: 8
|
|
Большое спасибо! Этот вариант выглядит намного интереснее. Прогоню его на имеющихся у меня тестовых вариантах, если возникнут вопросы - напишу.
Последний вопрос: задача в чем-то противоположная. Произвольно внутри текстовых блоков могут встречаться теги типа
< format value : 'value<">' name="name">
text<"'>text<break>text< break >text
< / format>
Вырезать их из текста не нужно, парсить их параметры не нужно. Нужно только заменить имеющиеся между открывающим и закрывающим тегами команды <break> на '\n'. И сделать это только для тегов <format>.
|
|
22.06.2019, 16:41
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
Сообщение от Tachyon
|
внутри текстовых блоков
|
Текстовый блок - это <block> или <text>?
|
|
25.06.2019, 09:02
|
Новичок на форуме
|
|
Регистрация: 19.06.2019
Сообщений: 8
|
|
Сообщение от Alexandroppolus
|
Текстовый блок - это <block> или <text>?
|
Видел в <text>, но, теоретически, может встретиться и в <block>.
В <block> точно встречается другой тег с такой же задачей (замена <break> на \n), выглядит немного иначе, но, если найти решение для <text>, думаю, я смогу адаптировать его и для второго.
Второй тег, встречающийся только в <block> выглядит так:
message("text<break>text")
Кавычки одинарные или двойные, пробелы произвольные. Думаю, здесь вполне подойдет подсказанное ранее решение - выборка текста до первого не заключенного в кавычки символа '>', только, соответственно, вместо кавычек скобка. А вот замена приходит в голову только через substr.
Последний раз редактировалось Tachyon, 25.06.2019 в 09:21.
|
|
26.06.2019, 10:00
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
Сообщение от Tachyon
|
Второй тег, встречающийся только в <block> выглядит так:
message("text<break>text")
|
Не понял. Т.е. тег на самом деле выглядит как вызов функции? Можно пример?
Сообщение от Tachyon
|
В <block> точно встречается другой тег с такой же задачей (замена <break> на \n), выглядит немного иначе, но, если найти решение для <text>, думаю, я смогу адаптировать его и для второго
|
Тоже давай пример
|
|
26.06.2019, 15:21
|
Новичок на форуме
|
|
Регистрация: 19.06.2019
Сообщений: 8
|
|
Ну так это и был пример. Это действительно выглядит как вызов функции, и в результате должно будет выводиться либо в alert, либо в console.log (но это уже совсем другая задача, с обработкой распарсенного в объекты текста, и ее я вполне себе решу самостоятельно). Мне очень понравилось предложенное Вами решение, в отличие от моего - должно работать значительно шустрее (насколько я понимаю). Если каким-то таким же образом получится решить и эту задачу - будет совсем прекрасно.
Я уже не буду утомлять уточнениями (например, в итоговом массиве объектов некоторые теги типа <text> и <block> должны объединяться, исходя из их свойств. Но это я тоже попробую разобраться в вашем примере и доделать самому.
А выглядеть в исходном тексте будет как-то так:
<value name='name<">1' value="value1">
<value name='name2' value = "еще <одно> значение">
<block name="name3" property="tagret" clear>
"текст"
<левый тег парсить="не нужно">
message ('text<">text<break>text' )
<value name='name3' clear value="value3">
</block>
<text name="text1" property="target">
<format name='form1'>
text<">text<break>text< break >text
</format>
<левый тег парсить="не нужно">
<value name='inner' clear value="inner">
<text clear name="text2" property="target">
второй текстовый блок, читается до конца.
<block name="inner block" property="tagret">
text text text
<format name='form1'>
text<">text<break>text< break >text
</format>
text text text
message("text< break>text")
<value name='inner' clear value="inner">
</block>
|
|
26.06.2019, 17:17
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
Сообщение от Tachyon
|
Ну так это и был пример. Это действительно выглядит как вызов функции, и в результате должно будет выводиться либо в alert, либо в console.log (но это уже совсем другая задача, с обработкой распарсенного в объекты текста
|
В общем случае это может быть совсем не другая задача. Например, если вдруг встретится message("aaa<value ...>bbb"), то, наверно, <value> парсить не надо, как если бы он просто был в тексте?
Тот же вопрос про случай <aaaa att="<value a=b>" > - тут у нас тег value попал в атрибут левого тега, и надо ли этот value парсить как обычный.
В общем, скорее всего, мой подход надо расширить на все активные элементы в тексте, обходить текст один раз, тогда ни на чем не споткнемся.
Если будет время, могу наброски сделать. Но хорошо бы все кейсы описать.
Последний раз редактировалось Alexandroppolus, 26.06.2019 в 17:19.
|
|
26.06.2019, 17:46
|
Новичок на форуме
|
|
Регистрация: 19.06.2019
Сообщений: 8
|
|
Сообщение от Alexandroppolus
|
Например, если вдруг встретится message("aaa<value ...>bbb"), то, наверно, <value> парсить не надо, как если бы он просто был в тексте?
|
Да, у message только текст. Но, теоретически, такого сочетания встречаться не должно. Если встретится - то это баг.
Сообщение от Alexandroppolus
|
Тот же вопрос про случай <aaaa att="<value a=b>" >
|
То же самое. Управляющих тегов в свойствах другого тега быть не должно. Только в теле между открывающим и закрывающим тегами. Или в корне. Точно так же не должно быть вложенных друг в друга блоков <block> или <format> (или любых других одинаковых тегов кроме <text>, с ним отдельная песня).
|
|
|
|