DOM я предполагаю, что Вы подразумеваете, что синтаксический анализатор читает весь документ сразу, прежде чем можно будет работать с ним. Обратите внимание, что высказывание, DOM имеет тенденцию подразумевать XML, в эти дни, но IMO, который не является действительно точным выводом.
Так, в ответе на Ваши вопросы - "Да", существует потоковый API и "Нет", DOM не является единственным путем. Тем не менее обрабатывая документ JSON, поскольку поток часто проблематичен в этом, много объектов не являются простыми парами поля/значения, но содержат другие объекты как значения, которые необходимо проанализировать для обработки, и это имеет тенденцию заканчиваться рекурсивная вещь. Но для простых сообщений можно сделать полезные вещи с находящимся на потоке/событии синтаксическим анализатором.
я записал синтаксический анализатор события получения по запросу для JSON (это был один класс, приблизительно 700 строк). Но большинство других, которое я видел, является ориентированным документом. Один из слоев, которые я создал сверху своего синтаксического анализатора, является устройством считывания с документов, которое взяло приблизительно 30 LOC. Я только когда-либо использовал свой синтаксический анализатор на практике в качестве загрузчика документа (по вышеупомянутой причине).
я уверен, ищете ли Вы сеть, Вы найдете получение по запросу и основанные на нажатии синтаксические анализаторы для JSON.
РЕДАКТИРОВАНИЕ: Я имею , отправил синтаксический анализатор на мой сайт для загрузки. Включены рабочий компилируемый класс и полный пример.
EDIT2: Вы также захотите посмотреть веб-сайт JSON .
Решение на чистом javascript
<select id="choice" multiple="multiple">
<option value="1">One</option>
<option value="2">two</option>
<option value="3">three</option>
</select>
<script type="text/javascript">
var optionsToSelect = ['One', 'three'];
var select = document.getElementById( 'choice' );
for ( var i = 0, l = select.options.length, o; i < l; i++ )
{
o = select.options[i];
if ( optionsToSelect.indexOf( o.text ) != -1 )
{
o.selected = true;
}
}
</script>
Хотя я согласен, что это следует делать на стороне сервера .
После нескольких тестов я достиг следующего регулярного выражения, которое позволяет избежать этой проблемы:^[+-]?[0-9]{1,3}
(?:(?<comma>\,?)[0-9]{3})?
(?:\k<comma>[0-9]{3})*
(?:\.[0-9]{2})?$
Это заслуживает некоторого объяснения:
^ [+ -]? [0-9] {1,3}
соответствует первому (от 1 до 3 ) цифры;
(? :(?
соответствует необязательной запятой, за которой следуют еще 3 цифры, и фиксирует запятую (или отсутствие one) в группе под названием 'запятая';
(?: \ k
соответствует любому повторению запятой, использованной ранее (если таковая имеется) за которым следуют 3 цифры;
(?: \. [0-9] {2})? $
соответствует необязательным "центам" в конце строки.
Конечно, это касается только #, ###, ## 0.00
(не #. ###. ## 0,00
), но вы всегда можете присоединиться к регулярным выражениям, как я сделал выше.
Окончательный ответ:
Теперь полное решение. Отступы и разрывы строк предназначены только для удобства чтения. редактировать 2 : текст добавлен; править 3 : добавлено второе решение; редактировать 4 : добавлено полное решение; править 5 : заголовки добавлены; редактировать 6 : добавлен захват; редактировать 7 : последний ответ разбит на две версии;
Сначала я бы использовал это регулярное выражение, чтобы определить, используется ли запятая или точка в качестве разделителя запятой (он выбирает последний из двух):
[0-9,\.]*([,\.])[0-9]*
Затем я бы удалил все другой знак (который не совпадал с предыдущим). Если совпадений не было, у вас уже есть целое число, и вы можете пропустить следующие шаги. Удаление выбранного знака может быть легко выполнено с помощью регулярного выражения, но есть также много других функций, которые могут сделать это быстрее / лучше.
После этого у вас останется число в виде целого числа, за которым следует запятая или точка, а затем десятичные дроби, где целочисленную и десятичную части легко можно отделить друг от друга с помощью следующего регулярного выражения.
([0-9]+)[,\.]?([0-9]*)
Удачи!
Изменить:
Вот пример, сделанный на Python, я предположим, что код должен быть самоочевидным, если это не так, просто спросите.
import re
input = str(raw_input())
delimiterRegex = re.compile('[0-9,\.]*([,\.])[0-9]*')
splitRegex = re.compile('([0-9]+)[,\.]?([0-9]*)')
delimiter = re.findall(delimiterRegex, input)
if (delimiter[0] == ','):
input = re.sub('[\.]*','', input)
elif (delimiter[0] == '.'):
input = re.sub('[,]*','', input)
print input
С помощью этого кода,
Как насчет
/(\d{1,3}(?:,\d{3})*)(\.\d{2})?/
, если вы хотите убедиться, что запятые точно разделяют каждые 3 цифры, или
/(\d[\d,]*)(\.\d{2})?/
, если нет.
Если я правильно интерпретирую ваш вопрос, так что вы говорите, что результат ДОЛЖЕН выглядеть так, как вы говорите, "будет" выглядеть, то я думаю, вам просто нужно оставить запятую вне класс символов, поскольку он используется как разделитель, а не часть того, что должно быть сопоставлено.
Так что избавьтесь от "." сначала, затем сопоставьте две части.
$value = "111,111.11";
$value =~ s/\.//g;
$value =~ m/(\d+)(?:,(\d+))?/;
$ 1 = начальные целые числа без точек $ 2 = либо undef, если он не существует, либо цифры после запятой, если они существуют.