Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Регулярные выражения: парные скобки (https://javascript.ru/forum/misc/56059-regulyarnye-vyrazheniya-parnye-skobki.html)

ziargon 27.05.2015 20:59

Регулярные выражения: парные скобки
 
Здравствуйте!

Необходимо крайние круглые скобки перед знаком деления (как и после) в формуле перевести в фигурные, а те круглые парные (и только парные) скобки что могут быть внутри (если есть) не трогать, какой бы они вложенности не были с помощью регулярного выражения
Например: перевести строку "2*x+((x+1)**2+(x+3)**2)/{x+1}-12" привести к виду "2*x+{(x+1)**2+(x+3)**2}/{x+2}-12"
Спасибо за помощь

рони 27.05.2015 21:42

ziargon,
<script>
   var str = "2*x+((x+1)**2+(x+3)**2)/{x+1}-12"
   document.write(str + "<br>" + str.replace(/\((.*?)\)(?=\/)/, "{$1}")   )
</script>

ziargon 27.05.2015 22:18

Спасибо))) Но не для всех случаев работает(
Например для (-(-(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 скобка парная, а вот вторая одиночная

ziargon 28.05.2015 00:36

Вроде есть способ проверки парности скобок через рекурсию, но я его не знаю и найти не могу

рони 28.05.2015 01:09

ziargon,
http://javascript.ru/forum/css-html/...teki-v-js.html

kostyanet 28.05.2015 11:21

Общий термин - токен и токенизатор.

ziargon 28.05.2015 18:12

рони,
Большое спасибо за подсказку. Немного модифицировав скрипт я сделал так:
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,
Надо будет почитать

рони 28.05.2015 22:31

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>

ziargon 29.05.2015 01:40

рони,
Спасибо, но к сожалению только с одной стороны от слэша скобки делает как нужно, а вот с другой не хочет. Я попробовал модифицировать Получилось сделать 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)})"

рони 29.05.2015 12:26

ziargon,
наверняка есть варианты решения, но уже неинтересно, вы дважды меняли условия задачи.


Часовой пояс GMT +3, время: 20:20.