2013-04-01 109 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