2011-01-24 6 views
5

흥미로운 점이 있습니다. 누구나 모든 (첫 번째)^(초)를 Math.pow ((첫 번째), (두 번째))로 변환하는 우수한 정규 표현식을 갖고 있습니까?RegEx 대신 pow (a, b)를 사용합니다.

편집 :

내가 가진 가장 지금까지 답변 지금까지 충분히 일반적으로하지 않습니다

s = s.replace(/((?:\d+\.?\d*)|\w+|\((?:(?:[^\(\)]*(?:\([^\(\)]*\)))*)\))\s*\^\s*((?:\d+\.?\d*)|\w+|\((?:(?:[^\(\)]*(?:\([^\(\)]*\)))*)\))/g, 'Math.pow($1, $2)') // replace expression^expression with Math.pow($1, $2) 

입니다. 그들은 (var1 + var2)^2와 같은 것을 다루지 않습니다. (var1 * (var2 + var3))^2

솔루션은 괄호로 작업해야합니다.

strfriend.com을 사용하면 정규식을 시각화 할 수 있습니다. 그게 내가 한 일이야.

+3

그리고 현재 가장 가까운 것은 ...? – Oswald

+4

'a * b^c'는 무엇으로 변환되어야합니까? 'a^b + c'? 'a^b^c'? –

+5

일반 정규식으로는이 작업을 수행 할 수 없습니다. 임의의 재귀가 필요합니다. 너가 현상금을 올릴 것을 제안하면 나는 이것이 공정하게 관련된 문제이다. – kelloti

답변

11

이것은 정규식 (적어도 많은 노력없이) 수행 할 수 없습니다. 단순한 정규 표현식으로 처리 할 수없는 다른 괄호 층을 고려해야합니다. 나는 수학적 표현을 파싱 할 수있는 라이브러리를 찾도록 제안한다. 또는 가능한 식을 간단한 정규식으로 처리 할 수있는 것으로 제한해야합니다.

동일한 정규 표현식에서 사용할 수있는 (역 참조 된) 정규식에 명명 된 및 균형 잡기 그룹을 정의 할 수 있습니다. 이를 통해 원하는 매개 변수 구문을 정의하고 두 매개 변수를 캡처해야합니다. 나는 바퀴를 재발 명하고 JS 라이브러리를 사용해서는 안된다. 당신이 그와 같은 소스 파일이나 뭔가를 변환 할 가정

http://snippets.dzone.com/posts/show/2207

+3

Mattias가 바로 여기 있습니다. 괄호 같은 중첩 된 구문을 가진 언어를 사용한다면, 정규 언어는 그것을 잘라 내지 않을 것입니다. 사실, 거기에는 '정규 언어'의 정의가 있습니다. 파서 작성을 시작하거나 여러 가지 방법 중 하나를 찾는 것이 더 좋습니다. –

2

당신은 String.replace을 사용할 수

> s = "hello 2^3 pow!" 
> s.replace(/(\d+)\^(\d+)/, "Math.pow($1, $2)") 
"hello Math.pow(2, 3) pow!" 
1

은 소스 파일을 통해 실행하는 펄 스크립트를 가지고 Math::Expression::Evaluator::Parser를 사용합니다. 개요에서 :

use Math::Expression::Evaluator::Parser; 

my $exp = '2 + a * 4'; 
my $ast = Math::Expression::Evaluator::Parser::parse($exp, {}); 
# $ast is now something like this: 
# $ast = ['+', 
#   2, 
#   ['*', 
#   ['$', 'a'], 
#   4 
#   ] 
#  ]; 

쉽게 지수를 처리 할 수있는 것처럼 보입니다. 따라서 귀하의 경우에 AST는 같은 것이다 :

# $ast = ['^', 
#   base, 
#   exp 
#  ]; 

당신이 원하는 표현 만들 수있다 'Math.pow을 (기본, EXP)'(재귀)가 '기본'과 '특급'에서 문자열을 재 조립하여 하위 트리.

JavaScript로 계산기를 구현하려는 경우 물론 JavaScript-Parser이 필요하거나 Math :: Expression :: Evaluator를 사용하여 구현 된 서버 백엔드에 의존 할 수 있습니다.

+0

JS 또는 이와 유사한 기능을 구현하는 방법을 설명하는 답변이 정답입니다. – Incognito

1

나쁜 소식 : 정규 표현식이 그것을 잘라 내지 않을 것입니다. (많은 답변에서 알 수 있듯이)이를 위해 파서를 작성해야합니다.

좋은 소식 : 재귀 적 파생 구문 분석기를 작성하여 거의 모든 언어에서 비교적 쉽게이 작업을 수행 할 수 있습니다. 가능한 한 많이 기존 코드를 재사용해야하지만 반복적 인 하향 파서를 직접 코딩 (그리고 선행 규칙을 인코딩하는 방법을 보는 것)은 순전히 계몽적인 경험을 위해 권장 될 수 있습니다.

컴파일러 구성에 대한 책을 들고 구문 분석에 대한 처음 몇 장을 읽으십시오. Niklaus Wirth가 this freely available book을 추천하겠습니다. 4.1 "재귀 적 강하 방법"을 찾아보십시오.

0
var caretReplace = function(_s) { 
    if (_s.indexOf("^") > -1) { 
     var tab = []; 
     var powfunc="Math.pow"; 
     var joker = "___joker___"; 
     while (_s.indexOf("(") > -1) { 
      _s = _s.replace(/(\([^\(\)]*\))/g, function(m, t) { 
       tab.push(t); 
       return (joker + (tab.length - 1)); 
      }); 
     } 

     tab.push(_s); 
     _s = joker + (tab.length - 1); 
     while (_s.indexOf(joker) > -1) { 
      _s = _s.replace(new RegExp(joker + "(\\d+)", "g"), function(m, d) { 
       return tab[d].replace(/(\w*)\^(\w*)/g, powfunc+"($1,$2)"); 
      }); 
     } 
    } 
    return _s; 
}; 
  1. console.log(caretReplace("(3*(f(x^2)-2)^2+1^5-g(2^3+1)^5)^(9-2^3)"));Math.pow((3*Math.pow((f(Math.pow(x,2))-2),2)+Math.pow(1,5)-Math.pow(g(Math.pow(2,3)+1),5)),(9-Math.pow(2,3)))을 제공합니다 확인하십시오.

  2. 당신의 수학 표현식은 균형이 잘 맞춰진 괄호와 닫힌 괄호로 유효해야합니다.

  3. Math.pow을 원하는 기능 이름으로 바꿀 수 있습니다.

  4. 나는 대부분의 안쪽에서 가장 바깥 쪽의 모든 괄호를 숫자가 아닌 텍스트 (___joker___0, ___joker___1 등)로 바꾸어서이 작업을 수행했습니다. 마지막에 나는 이러한 모든 문자열을 계층 적으로 구문 분석하여 괄호가 아닌 식에 캐럿을 대체합니다.

관련 문제