用于数学运算的PHP正则表达式

用于数学运算的PHP正则表达式,php,regex,Php,Regex,所以我试图创建一个正则表达式,但没有成功 这是我在输入字符串中得到的结果: String A: "##(ABC 50a- {+} UDF 69,22g,-) {*} 3##" String B: "##ABC 0,10,- DEF {/} 9 ABC {*} UHG 3-##" 这就是我需要从正则表达式中处理的内容: Result A: "(50+69,22)*3" String B: "0,10/9*3" 我就是不能把数字替换和操作符号结合起来 这就是我得到的: '/[^0-9\+\-\*

所以我试图创建一个正则表达式,但没有成功

这是我在输入字符串中得到的结果:

String A: "##(ABC 50a- {+} UDF 69,22g,-) {*} 3##"
String B: "##ABC 0,10,- DEF {/} 9 ABC {*} UHG 3-##"
这就是我需要从正则表达式中处理的内容:

Result A: "(50+69,22)*3"
String B: "0,10/9*3"
我就是不能把数字替换和操作符号结合起来

这就是我得到的:

'/[^0-9\+\-\*\/\(\)\.]/'

感谢您的帮助。

我不擅长正则表达式,但我找到了另一种方法:

在运行eval之前,请执行额外的输入检查

$string = "(ABC 50a- {+} UDF 69,22g) {*} 3";
$new ='';
$string = str_split($string);
foreach($string as $char) {
   if(!ctype_alnum($char) || ctype_digit($char) ){
    //you don't want letters, except symbols like {, ( etc
     $new .=$char;
   }
}
//echo $new; will output -> ( 50- {+}  69,22) {*} 3
//remove the brackets although you could put it in the if statement ...
$new = str_replace(array('{','}'),array('',''), $new);
//floating point numbers use dot not comma
$new = str_replace(',','.', $new);
$p = eval('return '.$new.';');
print $p; // -57.66
使用:


附言:我假设基础运算之前的负数是被考虑在内的。

一个简单的解决方案是去掉所有你不想要的东西

因此,请将其替换为:

\{(.+?)\}{^0-9,{}()]+}(?
使用
$1

很简单:

$input = "(ABC 50a- {+} UDF 69,22g,-) {*} 3";
$output = preg_replace('#\{(.+?)\}|[^0-9,{}()]+|(?<!\d),|,(?!\d)#', '$1', $input);
$input=“(ABC 50a-{+}UDF 69,22g,-){*}3”;

$output=preg\u replace('\{.+?)\}[^0-9,{}()]+|(?一个好的开始是用文字写下您想要匹配的模式。例如,您说过,您知道操作在
{}
中,但在第一次尝试正则表达式时,这不会出现在任何地方

您也可以将其分解为单独的部分,然后在以后构建。例如,您可能会说:

  • 如果你看到括号,把它们保留在最后的答案中
  • 一个数字由两个数字中的任意一个组成
  • …或后跟逗号和更多数字的数字
  • 一个操作总是用大括号括起来,可以是
    +
    -
    *
    /
  • 其他一切都应该扔掉
鉴于上述清单:

  • 匹配括号很容易:
    [()]
  • 可以使用
    [0-9]
    \d
    匹配一个数字;至少有一个是
    +
    ;所以“数字”是
    \d+
  • 逗号数字很简单:
    ,\d+
    ;使用
    将其设置为可选,您将获得
    \d+(,\d+)
  • 四个操作中的任何一个都只是
    [+*/-]
    ;转义
    /
    -
    以获得
    [+*\/-]
    不要忘记
    {
    }
    在正则表达式中有特殊的含义,因此需要作为
    \{
    \}
    转义;大括号中的操作列表变成:
    {[+*-/\}
现在我们必须把它们放在一起;一种方法是使用
preg\u match\u all
按顺序查找所有这些模式的出现,然后我们可以将它们粘在一起。所以我们的正则表达式就是“这个或这个或这个”:


我还没有测试过这个,但是给出了我是如何实现它的解释,希望你能想出如何测试它的一部分,并在必要时对其进行调整。

离开办公室之前,请快速尝试;-)

输出:

(ABC 50a- {+} UDF 69,22g) {*} 3 = ( 50 + 69,22 ) * 3
ABC 0,10- DEF {/} 9 ABC {*} UHG 3- = 0,10 / 9 * 3

如果有人喜欢摆弄代码,这里有一个活生生的例子:

你怎么会有一个包含额外数据的字符串,比如
ABC,UDF
?它真的可以包含所有内容。唯一可以确定的是,{}字符串中的操作可能更复杂?(即更多的括号组?)一个好的开始是用文字写下您想要匹配的模式。例如,您说过您知道操作在
{}
中,但是在您第一次尝试正则表达式时,它不会出现在任何地方。不要忘记
{
}
在正则表达式中有特殊的含义,因此需要作为
\{
\}
进行转义。这对给定的示例有效。不过,我担心它可能会在将来通过意外的输入,如果它们包含意外的逗号、括号或大括号。@IMSoP这正是我说需要更好的规范的原因。OP说“它真的可以包含所有的东西”,这没有多大帮助。你不能用给出的信息来构建一个lexer。我完全同意,只是想让读者意识到“黑名单”的危险"基于这样的方法。所有内容都有点宽泛。我的意思是它在大括号中包含数字、小数和数学运算。除此之外,所有内容都是可以预期的。但感谢到目前为止,我们将对其进行测试!我还添加了双叉,可以在文本中的表达式前后找到。它可以工作,但也可以捕获卷曲b球拍。你可以在:
/[()]|\d(,\d)?(?@fusion3k啊,是的,忘记了匹配的必要性,但放弃了大括号。试图避免像零宽度环视仪这样的高级功能;可能会将其他所有东西都抓取到捕获组中。我想最简单的欺骗就是删除
{/code>和
}
在运行正则表达式之后。
$data = array(
  "(ABC 50a- {+} UDF 69,22g) {*} 3",
  "ABC 0,10- DEF {/} 9 ABC {*} UHG 3-"
);

foreach($data as $d) {
  echo $d . " = " . extractFormula($d) . "\n";
}

function extractFormula($string) {
  $regex = '/([()])|([0-9]+(,[0-9]+)?)|\{([+\*\/-])\}/';
  preg_match_all($regex, $string, $matches);

  $formula = implode(' ', $matches[0]);
  $formula = str_replace(array('{', '}'),NULL,$formula);
  return $formula;
}
(ABC 50a- {+} UDF 69,22g) {*} 3 = ( 50 + 69,22 ) * 3
ABC 0,10- DEF {/} 9 ABC {*} UHG 3- = 0,10 / 9 * 3