2013-04-01 158 views
1

如何解析和匹配計算字符串?解析和匹配計算字符串

這是我的代碼:

$pattern = '/(?:\d+(?:\.\d+)?\D)+\d+(?:\.\d+)/'; 
$input = [ 
    '1.0+2.5*5.4', 
    '5*8-4' 
]; 
foreach($input as $string){ 
    preg_match($pattern, $string, $match); 
    print_r($match); 
} 

我想不出什麼我做錯了。

+0

'\ D'是'-'減去匹配你的表現公式。而且你有兩個匹配浮點的位置。但是沒有第二個佔位符用於''/'分區,也沒有最後一個數字。 – mario

+0

看到我的答案它的工作整數和浮動 –

回答

2

這是因爲 「?」 貪婪的,試試 「+」,如:

$pattern = '/(?:\d+(?:\.\d+)?\D)+\d+(?:\.\d+)/'; 
$input = '34.27-15.44/8.44'; 
echo $input."\n"; 
preg_match($pattern, $input, $match); 
print_r($match); 

至於你的編輯:

$pattern = '/(?:\d+(?:\.?\d+)?\D)+\d+/'; 
$input = [ 
    '1.0+2.5*5.4', 
    '5*8-4', 
    '5*8-4string', 
    'string5*8-4', 
    'string' 
]; 
foreach($input as $string){ 
    preg_match($pattern, $string, $match); 
    print_r($match); 
} 

它提供:

Array 
(
    [0] => 1.0+2.5*5.4 
) 
Array 
(
    [0] => 5*8-4 
) 
Array 
(
    [0] => 5*8-4 
) 
Array 
(
    [0] => 5*8-4 
) 
Array 
(
) 

因爲我懷疑你想要它。

http://codepad.viper-7.com/4FoQnB

+0

已經使你的變化..現在它與第一個輸入..第二個輸入與整數不起作用..已更新問題 – clarkk

+0

謝謝..正是我需要它去做! :) – clarkk

0

結果預計,鑑於你的表達。

請注意如何\D只能匹配一次(或隨機數)。 \D-匹配,因此沒有其他匹配/

你可能想通過將一個量詞在更大的表達式的一部分來解決這個問題,但讓我預測你會去面對這樣建議你使用一個循環,一個替代單一 operand-問題操作符 - 操作數三元組,退出時不能進行替換。這是因爲沒有單程正則表達式可以正確管理操作順序(,例如 PEMDAS)。

+0

但是,PCRE可以很好地匹配複雜的公式,包括運算符優先級和parens。你可以定義命名的子模式和'(?R'遞歸,如果你願意的話,它不再是一次通過。「 – mario

+0

@mario這並不意味着這是一個好主意:\ –

+0

@mario - 好點;忘了那些正則表達式extras。我不同意匹配和解析可以通過模式(單個或循環)完成。我認爲我的警告更多地是關於計算步驟,如果有的話。但是我可能會誤解。回答了這樣一個問題,它是[關於逆波蘭表示法](http://stackoverflow.com/questions/12293395/ruby-regexp-issue-involving-reverse-polish-calculator/12293553#12293553),這似乎勢在必行替換髮生在一個循環中,逐層進行。這可能不適用於中綴表示法。 –

0

試試這個。它適用於整形和浮點:

$pattern = '/(?:\d+(?:(\.|)\d*)?\D)*\d*(?:(\.|)\d+)/'; 
$input =array(
    '1.0+2.5*5.4', 
    '5*8-4', 
    '5*8-4string' 
); 
foreach($input as $string){ 
    echo "input:".$string."\n"; 
    preg_match($pattern, $string, $match); 
    print_r("output:".$match[0]."\n"); 
    } 

輸出:

input:1.0+2.5*5.4 
output:1.0+2.5*5.4 
input:5*8-4 
output:5*8-4 
input:5*8-4string 
output:5*8-4