2015-09-29 364 views
2

符號如何更換^到調用Math.pow(? 例如:替換字符串

str = "10 + 5.2^12"; // -> "10 + Math.pow(5.2, 12)" 
str = "2^(12) + 6"; // -> "Math.pow(2, 12) + 6" 
+2

你有沒有嘗試過一些代碼來實現這個目標?如果是這樣,請張貼相同。 –

+1

你在尋找一個表達式評估器嗎? –

+0

我不知道如何在regxp中描述 – Letfar

回答

0

您可以在Java正則表達式做到這一點。 使用下面的代碼片段來區分和替換字符串。

private static String replaceMatchPow(String pValue) { 
    String regEx = "(\\d*\\.*\\d*)\\^\\(*(\\d*\\.*\\d*)\\)*"; 
    Pattern pattern = Pattern.compile(regEx); 
    Matcher m = pattern.matcher(pValue); 
    if (m.find()) { 
     String value = "Math.pow(" + m.group(1) + "," + m.group(2) + ")"; 
     pValue = pValue.replaceAll(regEx, value); 
    } 
    return pValue; 
} 

正則表達式如何工作? 下面是輸入 「2 ^(12)+ 6」 第一組的示例
\ d *(\ d * \ \ d。) - >匹配位數[0-9], * - >零到無限 \^- >劃分組由^符號 (* - >左支架,*表示發生零到無限 第二組(\ d * \ \ d
)* - >右托架

結果:第一組值是2和第二組值是12


/(\d*.*\d*)\^(*(\d*.*\d*))*/
第一捕獲組(\ d *。* \ d *)
\ d *匹配位數[0-9]
量詞:*之間的零和無限次,多次可能的,根據需要回饋[貪婪]
*的字符匹配。字面上
量詞:*之間的零和無限次,儘可能,用之於根據需要多次[貪婪]
\ d *匹配位數[0-9]
量詞:*之間的零和無限次,多次,儘可能需要回饋[貪婪]
\ ^匹配字符^字面上
(*字符(字面
量詞匹配:*之間的零和無限次,多次儘可能根據需要回饋[貪婪]
第二捕獲組(\ d *。* \ d *)
\ d *匹配位數[0-9]
量詞:*之間的零和無限次,多次可能的,根據需要[貪婪]
回饋*匹配人物 。字面上
量詞:*之間的零和無限次,儘可能,用之於根據需要多次[貪婪]
\ d *匹配位數[0-9]
量詞:*之間的零和無限次,多次地,用之於需要[貪婪]
)*匹配的字符)的字面
量詞:*之間的零和無限的時間,儘可能地,用之於根據需要多次[貪婪]

+0

你能解釋RegEx嗎? –

+0

例如:第一組(\\ d * \\。* \\ d *)\ d * - >匹配數字[0-9],* - >零至無限制 –

+0

\\^- >符號 –

1

你可以這樣說:

str = str.replaceAll("\\(?(\\d+\\.?\\d*)\\)?\\^\\(?(\\d+\\.?\\d*)\\)?", "Math.pow($1,$2)"); 

在這種情況下,你正在尋找2組數字(\\d+\\.?\\d*),這可能是一個浮點值,可以是內部()\\(?\\)?。在這兩組之間,您需要有^號\\^。如果匹配,則方法的replaceAll替換所有這種模式與Math.pow($1,$2),其中$ 1和$ 2將與數字的第一和第二基團取代。

但是有一點,它可能會導致錯誤的結果,如果你有一個複雜的表達式,用2次乘法一排,就像一個10.22^31.22^5。在這種情況下,這個正則表達式應該更加複雜。也許你應該使用其他一些算法來解析這些表達式。

+0

你能解釋RegEx嗎? –

+0

已經在編輯答案。添加了簡短的解釋 – Stanislav

+0

誰downvoted,爲什麼? – bvdb

0

針對您的特殊問題y ou應該查找脫字符^ Java regular expressions中應該如何轉義,應該是\^

注意的是:在Java源代碼的字符串中

反斜槓被解釋 所要求的Java™語言規範中是Unicode 逃逸(第3.3節)或其他字符轉義(3.10.6節)因此, 需要在字符串文字中加上反斜槓, 代表正則表達式,以保護它們免受Java字節碼編譯器的解釋影響( )。

所以,你最終以"\\^"作爲Java String

但是一般情況下,您將爲算術表達式編寫解析器和解釋器。

該主題被稱爲編譯器構造,並依賴於有限自動機和正式語言的知識。

一個很好的例子可以在Bjarne Stroustrup的「C++編程語言第四版」第10.2章「桌面計算器」中找到。 (是的,我知道你想用Java編碼,請繼續閱讀)。 設有這種形式文法:

program: 
    end //end is end-of-input 
    expr_list end 

expr_list: 
    expression print //pr intis newline or semicolon 
    expression print expr_list 

expression: 
    expression + term 
    expression − term 
    term 

term: 
    term/primary 
    term ∗ primary 
    primary 

primary: 
    number //number is a floating-point literal 
    name //name is an identifier 
    name = expression 
    −primary 
    (expression) 

斯特勞斯展示瞭如何在一個類似的結構代碼如下:

double expr(bool get) //add and subtract 
{ 
    double left = term(get); 
    for(;;) { //‘‘forever’’ 
    switch(ts.current().kind) { 
    case Kind::plus: 
     left += term(true); 
     break; 
    case Kind::minus: 
     left −= term(true); 
     break; 
    default: 
     return left; 
    } 
    } 
} 

這個代碼體現語法的這一部分:

expression: 
    expression + term 
    expression − term 
    term 

這技術被稱爲遞歸下降,因爲語法中的遞歸將被實現爲遞歸函數cal l在相應的代碼中。對於Java開發人員來說,精選的相關C++代碼也應該是可以理解的。

一旦你對語法和如何實現它們有一些瞭解, 見例如Unambiguous grammar for exponentiation operation 如何以這種方式處理指數運算,即通常的運算符優先級規則得以實現。