用于数学运算的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