Регулярные выражения: парные скобки
Здравствуйте!
Необходимо крайние круглые скобки перед знаком деления (как и после) в формуле перевести в фигурные, а те круглые парные (и только парные) скобки что могут быть внутри (если есть) не трогать, какой бы они вложенности не были с помощью регулярного выражения Например: перевести строку "2*x+((x+1)**2+(x+3)**2)/{x+1}-12" привести к виду "2*x+{(x+1)**2+(x+3)**2}/{x+2}-12" Спасибо за помощь |
ziargon,
<script> var str = "2*x+((x+1)**2+(x+3)**2)/{x+1}-12" document.write(str + "<br>" + str.replace(/\((.*?)\)(?=\/)/, "{$1}") ) </script> |
Спасибо))) Но не для всех случаев работает(
Например для (-(-(4*x**2+12))/(x**3+6*x)) Вместо (-{-(4*x**2+12)}/(x**3+6*x)) получается {-(-(4*x**2+12)}/(x**3+6*x)). В полученном внутри 1 скобка парная, а вот вторая одиночная |
Вроде есть способ проверки парности скобок через рекурсию, но я его не знаю и найти не могу
|
|
Общий термин - токен и токенизатор.
|
рони,
Большое спасибо за подсказку. Немного модифицировав скрипт я сделал так: function balance(a) { for (var d = /(\u0028)[^\u0028]*?$/, e = { "(": /\u0028([^\u002F]*?)\u0029/ //скобка которая остается }, b, c = !0; c;) b = a, a = a.replace(d, function (a, b) { return a.replace(e[b], "[$1]") }), b == a && (c = !1); return a }; var qq = balance("int(-(-(4*x**2+12))/(x**3+6*x))=5+((2*log(x))/(log(x**2+6)))"); var pp1 = new RegExp("\\[(.*)\\]\\/\\[(.*)\\]", "g"); qq = qq.replace(pp1, "\\frac{$1}{$2}"); var pp21 = new RegExp("\\[", "g"); var pp22 = new RegExp("\\]", "g"); qq = qq.replace(pp21, "("); qq = qq.replace(pp22, ")"); alert(qq); Но он работает только для одной дроби. Возможно сделать, если в строке нескольких дробей? Пока вижу одно решение - порезать строку на части с дробями, но может есть попроще вариант kostyanet, Надо будет почитать |
ziargon,
<script> function balance(a) { for (var d = /(\u005B|\u0028|\u007B)[^\u005B\u0028\u007B]*?$/, e = { "(": /\u0028[^\u007D\u005D]*?\u0029/, "[": /\u005B[^\u0029\u007D]*?\u005D/, "{": /\u007B[^\u0029\u005D]*?\u007D/ }, b, c = !0; c;) b = a, a = a.replace(d, function (a, b) { return a.replace(e[b], "") }), b == a && (c = !1); return !/[\u005B\u005D\u0028\u0029\u007B\u007D]/.test(a) }; function foo(a) { for (var c = /\((.*?)\)(?=\/)/g, e = /\((.*?)\)(?=\/)/, d, b = 0; d = c.exec(a); b++) balance(d[0]) && (b--, a = a.slice(0, b) + a.slice(b).replace(e, "{$1}")), c.lastIndex = b; return a }; var str = "(-(-(4*x**2+12))/(x**3+6*x)) int(-(-(4*x**2+12))/(x**3+6*x))=5+((2*log(x))/(log(x**2+6)))" document.write(str + "<br>" + foo(str)) </script> |
рони,
Спасибо, но к сожалению только с одной стороны от слэша скобки делает как нужно, а вот с другой не хочет. Я попробовал модифицировать Получилось сделать 2. Для работы одной нужна лишняя дробь (это уже костыль), другая самую последнюю скобку неправильно делает Есть ли возможность сделать так, чтобы переводились с обеих сторон от слэша? Двойной слэш сделать можно (если понадобится), конфликтов не будет Например, переводило бы "\\int(-(-(4*x**2+12))/(x**3+6*x))=5+((2*log(x))/(log(x**2+6)))" в "\\int(-{-(4*x**2+12)}/{x**3+6*x})=5+({2*log(x)}/{log(x**2+6)})" |
ziargon,
наверняка есть варианты решения, но уже неинтересно, вы дважды меняли условия задачи. |
Часовой пояс GMT +3, время: 20:20. |