2011-01-24 29 views
5

के बजाय^^ बी के लिए RegEx यहां एक दिलचस्प है। किसी के पास सभी (पहले)^(सेकेंड) से Math.pow ((पहले), (सेकेंड) में कनवर्ट करने के लिए एक अच्छा RegEx है?पावर (ए, बी)

संपादित करें:

सबसे अच्छा मैं अब तक है

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

'ए * बी^सी' को किस रूप में परिवर्तित करना चाहिए? 'ए^बी + सी'? 'ए^बी^सी'? –

+5

यह सामान्य रेगेक्स के साथ नहीं किया जा सकता है। इसे मनमाने ढंग से रिकर्सन की आवश्यकता है। यदि आप एक उत्तर चाहते हैं तो मेरा सुझाव है कि आप बक्षीस बढ़ाएं, यह एक काफी शामिल समस्या है। – kelloti

उत्तर

11

इस regex (कम से कम प्रयास की बहुत सारी के बिना नहीं) के साथ नहीं किया जा सकता है। आपको कोष्ठक की विभिन्न परतों पर विचार करना होगा, जिसे एक साधारण नियमित अभिव्यक्ति के साथ संभाला नहीं जा सकता है। मैं गणितीय अभिव्यक्ति को पार्स करने में सक्षम पुस्तकालय की तलाश करने का सुझाव देता हूं। या आपको संभावित अभिव्यक्ति को उस चीज़ पर सीमित करना होगा जिसे आप सरल रेगेक्स से संभाल सकते हैं।

एक नियमित अभिव्यक्ति में नामित और संतुलित कैप्चर समूहों को परिभाषित करने की संभावना है जिसे एक ही नियमित अभिव्यक्ति में उपयोग किया जा सकता है (बैकरेफरेंस)। इसके साथ आपको गणित वाक्यविन्यास के वांछित सबसेट को परिभाषित करना होगा और पैरामीटर के लिए दोनों कैप्चर करना होगा। मेरा सुझाव है कि आपको पहिया को फिर से शुरू नहीं करना चाहिए और जेएस लाइब्रेरी का उपयोग नहीं करना चाहिए।

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

+3

मैटियास यहां है; यदि आपके पास अभिभावकों की तरह नेस्टेड संरचनाओं वाली भाषा है, तो एक नियमित भाषा बस इसे काट नहीं देगी - असल में, इसकी 'नियमित भाषा' की परिभाषा में है। एक पार्सर लिखना शुरू करना बेहतर है, या वहां से कई लोगों में से एक को ढूंढना बेहतर है। –

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 
#   ] 
#  ]; 

ऐसा लगता है कि exponentiations आसानी से संभाल सकते हैं। तो अपने मामले में एएसटी की तरह कुछ होगा:

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

आप वांछित अभिव्यक्ति बना सकते हैं 'Math.pow (आधार, exp)' द्वारा (रिकर्सिवली) 'आधार' और 'exp' से एक स्ट्रिंग पुनः subtrees।

यदि आप जावास्क्रिप्ट में कैलकुलेटर लागू करना चाहते हैं तो आपको निश्चित रूप से JavaScript-Parser की आवश्यकता है या आप मैथ :: अभिव्यक्ति :: मूल्यांकनकर्ता का उपयोग करके लागू सर्वर-बैकएंड पर भरोसा कर सकते हैं।

+0

यह, या जेएस में समान कार्यक्षमता को लागू करने पर चर्चा करने वाला एक उत्तर सही उत्तर है। – Incognito

1

बुरी खबर: नियमित अभिव्यक्ति इसे काट नहीं पाएगी (जैसा कि कई उत्तरों इंगित करते हैं), आपको इसके लिए एक पार्सर लिखना होगा।

अच्छी खबर: आप एक रिकर्सिव वंश पार्सर लिखकर लगभग किसी भी भाषा में अपेक्षाकृत आसानी से ऐसा कर सकते हैं। आपको निश्चित रूप से जितना संभव हो सके मौजूदा कोड का पुन: उपयोग करना चाहिए, लेकिन एक रिकर्सिव वंश को अपने आप को पार्सर (और देखकर कि आप प्राथमिकता नियमों को कैसे एन्कोड करते हैं) को कोडिंग करना पूरी तरह से प्रबुद्ध अनुभव के लिए अनुशंसित किया जा सकता है।

कंपाइलर निर्माण पर कोई भी पुस्तक उठाएं और पार्सिंग पर पहले कुछ अध्याय पढ़ें। मुझे निकलॉस विर्थ द्वारा this freely available book की अनुशंसा करते हैं, 4.1 "रिकर्सिव वंश की विधि" के लिए देखो।

0

एक जावास्क्रिप्ट पार्सर जनरेटर जेसन पर एक नज़र डालें।

विशेष रूप से करते हैं, उनकी calculator demo

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, आदि) के साथ। अंत में मैं गैर-कोष्ठक अभिव्यक्तियों पर कैरेट को प्रतिस्थापित करने के लिए, इन सभी तारों को पदानुक्रमित रूप से पार्स करता हूं।

संबंधित मुद्दे