Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Замена через replace, используя регулярки (https://javascript.ru/forum/misc/51627-zamena-cherez-replace-ispolzuya-regulyarki.html)

ОмаЭль 13.11.2014 15:05

Замена через replace, используя регулярки
 
Необходимо сделать так,что при вводе выражения в строку input выражение вычислялось. Но пользователь вбивает только (к примеру) cos(x), как известно JS вычесляет его только так : Math.cos(x); Вот код но я не могу понять что не так, ни хватает опыта и практики =(
<html>
<head>
<script type="text/javascript">
function zap(){
var a=document.all.a.value;
a=String(document.all.a.value);
a.replace(/cos(x)/gi,"Math.cos(x)");
var x=1;
a=eval(a);
alert(a);

}

</script>
</head>
<body>
<br><br><br><br>
<input type="text" value="10+cos(x)" name="a">

<input type="button" value="запуск" OnClick="zap()">
<br><br>
<table id="fig">
<tr>
<td></td>
<td></td>


</tr>
</table><br><br><br><br>

</body>
</html>

рони 13.11.2014 15:21

ОмаЭль,
:blink: ещё один
http://javascript.ru/forum/misc/5115...jj-zameny.html

Sweet 13.11.2014 15:27

Во-первых, скобки - это спец. символы в регулярках и их надо экранировать:
var string = "10+cos(x)";

alert([
  /cos(x)/gi.test(string), // false
  /cos\(x\)/gi.test(string), // true
  /cos(x)/gi.test("10+cosx") // true
]);

Во-вторых, раз уж эвалишь, используй with:
<script type="text/javascript">

function zap(){
var source = a.value;
var toExecString = "with (Math) return " + source;
var result = Function("x", toExecString)(1);

alert(result);
}

</script>

<input type="text" value="10+cos(x)" id="a">
<br>
<input type="button" value="запуск" OnClick="zap()">

krutoy 13.11.2014 18:31

<html>
<head>
<meta charset="windows-1251">
</head>
<body>
<input type="text" value="10+sin(1)" id="a">
<input type="button" value="запуск" OnClick="zap()">
<script>
function zap(){
var a=document.querySelector("#a").value
var test=function(){
   var re=/\s*(\d+)\s*([-+*\/])\s*(cos|sin)\s*\(\s*(\d+)\s*\)\s*/i
   if(!re.test(a)) return alert ("NO valid data")
   var expr=a.match(re),
       dig=(+expr[1]),
       operator=expr[2],
       resultOfFunc=Math[expr[3]](+expr[4]),
       result=dig+operator+resultOfFunc
  return eval(result)

}
alert (test())
}
</script>

</body>
</html>

krutoy 13.11.2014 18:33

Цитата:

Сообщение от Sweet
раз уж эвалишь, используй with:

Странная логика. with выпиливают из стандарта, а eval никуда не делся.

Аркадий Укупник 14.11.2014 03:14

не так все делается. калькулятор так не сделаешь. можно конечно тупо eval'ом, но лучше сделать по уму. для начала входной текст нужно разбить на токены. потом читаем про обратную польскую нотацию на википедии и создаем расово верный калькулятор.

krutoy 14.11.2014 13:18

Цитата:

Сообщение от Аркадий Укупник
но лучше сделать по уму. для начала входной текст нужно разбить на токены. потом читаем про обратную польскую нотацию на википедии и создаем расово верный калькулятор.

Причем тут обратная польская запись?
Если надо без эвала, можно вот так сделать:
<html>
<head>
<meta charset="windows-1251">
</head>
<body>
<input type="text" value="10+sin(1)" id="a">
<input type="button" value="запуск" OnClick="zap()">
<script>
function zap(){
var a=document.querySelector("#a").value
var test=function(){
   var re=/\s*(\d+)\s*([-+*\/])\s*(cos|sin)\s*\(\s*(\d+)\s*\)\s*/i
   if(!re.test(a)) return alert ("NO valid data")
   var expr=a.match(re),
       dig=(+expr[1]),
       operator=expr[2],
       resultOfFunc=Math[expr[3]](+expr[4]),
       
       sum=function(x, y){return x + y},
       mul=function(x, y){return x * y},
       div=function(x, y){return x / y},
       sub=function(x, y){return x - y},

       getResult=function(operator){
           return operator(dig, resultOfFunc)
       }
          switch(operator){
             case "+": return getResult(sum)
             case "-": return getResult(sub)
             case "*": return getResult(mul)
             case "/": return getResult(div)
       }
}
alert (test())
}
</script>
 
</body>
</html>


Если писать каждую хуйню вручную, позаниматься числоебством -- это умно, а сократить запись, сделать код лаконичным и выразительным -- это тупо, тогда это вариант для "умных".

рони 14.11.2014 13:24

krutoy,
:-?
Цитата:

-5 + -5
NO valid data

krutoy 14.11.2014 13:26

рони,
Так и должно быть. Мы же ожидаем, ввод sin или cos вторым подвыражением

krutoy 14.11.2014 13:34

рони,
Я же тут не собирался настоящий калькулятор писать с произвольным синтаксисом, просто накидал прототип решения для частного случая, с подстановкой Math. Можно и любое выражение обработать, но это уже другая история, это будет мини-язык, фактически. Тансляция из текстового поля в JS. Оно мне надо, голову забивать? ТС спрашивал только про Math. Дальше пусть сам думает:)

ОмаЭль 16.11.2014 17:37

Цитата:

Сообщение от krutoy (Сообщение 340781)
<html>
<head>
<meta charset="windows-1251">
</head>
<body>
<input type="text" value="10+sin(1)" id="a">
<input type="button" value="запуск" OnClick="zap()">
<script>
function zap(){
var a=document.querySelector("#a").value
var test=function(){
   var re=/\s*(\d+)\s*([-+*\/])\s*(cos|sin)\s*\(\s*(\d+)\s*\)\s*/i
   if(!re.test(a)) return alert ("NO valid data")
   var expr=a.match(re),
       dig=(+expr[1]),
       operator=expr[2],
       resultOfFunc=Math[expr[3]](+expr[4]),
       result=dig+operator+resultOfFunc
  return eval(result)

}
alert (test())
}
</script>

</body>
</html>

К сожалению мне малость не понятна конструкция with : собственно как она работает просто при добавлении как текст к переменной source.
И можешь еще помочь с отображением, вот написал код на добавление элементов к уже существующей таблице, но не работает. Вот сам код:
<html>
<head>
<style type="text/css">
table,tr,td {border:1px solid black;}

</style>
<script type="text/javascript">

function zap(){
var h=1;
var source = document.all.a.value;
var toExecString = "with (Math) return " + source;
var result = Function("x", toExecString)(h);//значение x

return result;
}


function zap1(){
var kolvo=6;
for(var i=1;i<=kolvo;i++){
zap();
var obEl=document.getElementById("fig"); //обращение к существующей таблице
var newRow=obEl.insertRow(i); // создание строки
var newCell = newRow.insertCell(0);//создание 1 столбца
zap();
newCell.innerHTML=result; // заполнение 1 столбца
var newCell = newRow.insertCell(1); //создание второго столбца
newCell.innerHTML="2 аналогично 1-ой"; //заполнение 2 столбца
document.body.appendChild(obEl);}// делает эл дочерним

}

</script>
</head>
<body>
<br><br><br><br>
<input type="text" value="cos(x)" name="a">

<input type="button" value="запуск" OnClick="zap1()">
<br><br>
<table id="fig">
<tr>
<td></td>
<td></td>


</tr>
</table><br><br><br><br>

</body>
</html>

krutoy 17.11.2014 00:06

Цитата:

Сообщение от ОмаЭль
К сожалению мне малость не понятна конструкция with : собственно как она работает просто при добавлении как текст к переменной source.

stringFromInput="cos(x)"//получаем строку из поля ввода
result=Function("x", "with(Math) return "+stringFromInput) (1)
//1) "with(Math) return "+stringFromInput вычисляется в "with(Math) return "+"cos(x)"
//2) "with(Math) return "+"cos(x)" вычисляется в строку "with(Math) return cos(x)" -- строки конкатенируются
//3) выражение Function("x", "with(Math) return cos(x)" ) раскрывается в function (x) { with(Math) return cos(x) }
//4) выполняется инлайн (function (x) { with(Math) return cos(x) })(1) , происходит подстановка 1 на место x
//5) выполняется выражение with(Math) return cos(1), результат возврата записывается в переменную

// with(Math) return cos(1), в твоем случае, это то же что return Math.cos(1)

Вообще, with, это довольно мудреная конструкция, особенно в плане работы с прототипами и глобальной областью. Но в общем случае, ты можешь считать, что она выполняет выражения-свойства и методы в контексте указанного объекта. например
with(Math) alert(sin(1)+cos(1))

Имей в виду, что ее, к сожалению, выкинули из стандарта.

Цитата:

Сообщение от ОмаЭль
помочь с отображением

Честно говоря, я не понял, что ты хочешь. Напиши лучше словами, опиши задачу, подробно.

krutoy 17.11.2014 00:29

ОмаЭль,
Ты, кстати, тут и без with мог бы легко обойтись. Тут у тебя она определяющего смысла не имеет, просто сахар, как обычно.
stringFromInput="cos(x)"//получаем строку из поля ввода
result=Function("x", "return Math."+stringFromInput)(1)
alert(result)

ОмаЭль 17.11.2014 19:18

Цитата:

Сообщение от krutoy (Сообщение 341237)
Честно говоря, я не понял, что ты хочешь. Напиши лучше словами, опиши задачу, подробно.

Ну мне необходимо что бы результаты вычислений добавлялись в динамически изменяемую таблицу. Но это я уже исправил:
function zap(){
var source = document.all.a.value;
var toExecString = "with (Math) return " + source;
result = Function("x", toExecString)(h);//значение x
h=result;

return result;
}

Область видимости у result спутал, вечером уже не заметил =(
На данный момент, есть еще проблемка но сначала попробую решить сам =)


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