2010-12-22 34 views
1

首先,我從來不明白這麼好正則表達式模式,但我進步:)正則表達式POW()我只想說的

我想更換創建函數「^」 char和左右匹配pow($ 1,$ 2)。我manged去,我從一個API接收點是可以接受的,但字符串不斷變大&更大,現在我卡住了...是這樣的:

$str = '(0+1*9^3+3)*(4+5)-(6/7)+(1+2)/(1+1)^((2/3)*3-1+(2/3))'; 
$str = preg_replace('/([0-9]+|\([0-9\+\-\*\/]+\)|[^\+\-\*\/]\([\S]+\))\^([0-9]+|\([0-9\+\-\*\/]+\)|[^\+\-\*\/]\([\S]+\))/', 'pow($1,$2)', $str); 
echo $str; 

該工程確定給定字符串,但如果我再加1個「+(1 + 2)/(1 + 1)^((2/3)* 3-1 +(2/3))'」到最後它不能正常工作。

基本上我想要的preg_replace找到的第一個「()」從左邊&第一「()」,從「^」字符的應該是如何工作的

實例的權利(我只能做對於左側「^」,但它可以應用於以及右側)

3+2^3-2 => 3+pow(2, 3)-2 
3+(1+1)^3*2 => 3+pow((1+1), 3)*2 
3+(1+1+(1+2))^3/2 => 3+pow((1+1+(1+2)), 3)/2 
3+((3/3)+(2/2))^2-1 => 3+pow(((3/3)+(2/2)), 2)-1 
(3+1)^3-1 => pow((3+1), 3)-1 

等等

排序的所有上面: 回報「$ 1」是什麼之前「 ^「: 1.如果」^「之前的第一件事是int,返回數字 2.如果第一件事是「)」搜索它的對「(」並返回裏面的一切(像'/(/([.*]))\^/')

我很抱歉我的英語,我希望你明白...我希望有人可以幫助我解決這個問題:(

在此先感謝!

回答

3

這裏的問題是你需要一個解析器。無限嵌套的表達式(如括號中所示)不能僅由正則表達式匹配。考慮一下:

(2^(2^(2^(2^(2^(2^(...))))))) 

什麼正則表達式會匹配那個?你可以近似它,你可以匹配N級,但你不能做到這一切。

應該做一個分析器。如果你不想,我明白,因爲這是很多工作。您現在可能可以獲得足以滿足您的目的的正則表達式解決方案。但它不會永遠工作,因爲正則表達式不足以解決這個問題。


  1. 的Perl(和Per​​l兼容的正則表達式)可以做到這一點,但他們不應該。一旦你開始使用Perl的正則表達式的這些功能,它變得不可讀。此外,他們不是(理論上講)常規表達式,但沒有人真的關心理論。 :P