Просмотр полной версии : Парсер строкового выражения в математическое
Всем привет. Возникла тут задача по преобразованию различных строковых выражений в число, наткнулся на эту тему - http://www.flasher.ru/forum/showthread.php?t=149679&highlight=%F1%F2%F0%EE%EA%F3+%E2+%F7%E8%F1%EB%EE
К сожалению с регулярками не очень знаком, в принципе пример автора все считает, но есть одно НО:
Положим есть такая запись - 2+3+NaN+5, выше приведенный пример выдаст 5, то есть NaN+5 он просто проигнорирует(ведь там используется parseFloat, а он вырезает все "не числа"). Как можно организовать парсер, чтобы например такой ряд - NaN+NaN+2+3+NaN+4 выдавал 9?
ps_spectre
11.03.2011, 19:19
Не ясна задача. В заголовке одно, по факту совсем другое надо.
Такую простую строку можно и не думая парсить.
var s:Array = "NaN+NaN+2+3+NaN+4".split("+");
var l:uint = s.length;
var sum:Number = 0.0;
var n:Number = 0.0;
while (l --> 0)
{
n = parseFloat(s[l]);
if (n) sum += n;
};
trace (sum); // 9
а если надо полноценные мат. выражения парсить, то проще готовый парсер взять.
Парсить нужно арифметические действия, как в начальной школе:) сложение,деление,умножение,вычитание, скобки могут быть. Так же в строке встречаются "не числа", которые при сложении надо игнорировать, а вот к примеру при делении или умнодении выдавать NaN.
ps_spectre
11.03.2011, 19:48
scarbo, тогда гораздо сложнее. (
Надо искать готовый, подходящий парсер.
Самому писать не особо много удовольствия.
Но если вдруг решите, то проще через обратную польскую нотацию. (вики) (http://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D1%81%D0%BA%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C)
вроде в гугле находятся какие-то парсеры...
но фича в этой строке
встречаются "не числа", которые при сложении надо игнорировать, а вот к примеру при делении или умнодении выдавать NaN.
Это "кастомное" условие. Обычно "3 + NaN + 3" == "NaN". А если надо по-другому, то уже искать обходные пути.
Вот-вот, там по ссылке нормальный вроде бы парсер, но блин с регулярками затык.
Да про метод дейкстры я уже прочитал, что-то совсем не радостно стало.
Это "кастомное" условие. Обычно "3 + NaN + 3" == "NaN". А если надо по-другому, то уже искать обходные пути.
То есть должно получиться типа как в Екселе - там если назначить одной ячейке сумму других, то их можно заполнять хоть с низу, хоть сверху, результат будет. Может попробовать сортировать, все NaN из суммы в конец строки запихнуть, их все равно parseFloat отрежет, ну или вырезать их регуляркой, а вот умножение и деление, не трогать?
ps_spectre
11.03.2011, 20:23
Если вдруг захочется обойтись малой кровью, и ничего не придумывать,
то советую пересмотреть условия попадания NaN в строку:
1. по-хорошему чтобы вообще не было NaN
2. взять за основу то, что NaN + any_number == NaN (так и должно быть)
3. заменить все NaN в строке на 0 или удалить вообще из строки.
4. хуже вариант: самому парсить строку и учитывать какой стоит знак перед/после NaN (но тут уже не далеко и до обратной польской нотации)
по-простому все NaN в строке поменять на 0 и самым простым способом распарсить можно так:
var parseString:String = "(((10 + 15 + NaN) + 5) * 3 + (10 * NaN)) / 2";
parseString = parseString.replace(/[NaN]/gi, "0");
if (ExternalInterface.available)
{
var parse:Number = ExternalInterface.call("eval", parseString);
trace(parse);
}
а парсер взять нативный, который есть в js. (eval) Минус подхода -- не будет в standalone плеере работать.
Вообщем, задача творческая, и решение нужно подобрать самому.
-----
если в задаче не особо критично
5 * NaN == NaN
то
5 * 0 == 0
и тогда все NaN в строке легко меняем на 0 и не паримся
тогда
5 + 3 + NaN + 2 + NaN == 10
вроде кто-то писал в блоге про такую штуку
UPD: нашел (http://www.flasher.ru/forum/blog.php?b=287)
хотя я код не стал смотреть - больно там жутко, да и комменты не самые лучшие, но может на что-то подтолкнет
ps_spectre, про eval() интересную мысль предложили, eval() в Js умеет парсить математические выражения?Круто если так. Весь проект в браузере, так что stand olone не страшен.
Jewelz, да я видел этот пост и его продолжение тоже.
ps_spectre
11.03.2011, 23:22
scarbo, eval() умеет парсить джаваскрипт код ,)
а мат. выражения это частный случай как раз.
вот только 5 + NaN == NaN.
что собственно и логично.
в as3 тоже самое: 5 + NaN == NaN.
Вообщем, что-то с NaN в строке надо делать. От этого потом и исходить.
Кастомный парсер написать на крайняк.
Нет, все таки ExternalInterface - это не стабильное решение. Я просто буду заменять NaN на 0 в формуле, там просто вся задачка завязана на статистике, где 0 и null(NaN в моем случае) это разные вещи.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.