我想操作像"…4+3(4-2)-...."这样的字符串成为"…4+3*(4-2)-....",但当然它应该识别任何数字, d,后面跟着一个'('并将其更改为'd*('。如果可能的话,我还想同时将')('改为')*('。如果有可能添加对pi或e等常量的支持,那就太好了。
现在,我只是这样做:
private function make_implicit_multiplication_explicit($string)
{
$i=1;
if(strlen($string)>1)
{
while(($i=strpos($string,"(",$i))!==false)
{
if(strpos("0123456789",substr($string,$i-1,1)))
{
$string=substr_replace($string,"*(",$i,1);
$i++;
}
$i++;
}
$string=str_replace(")(",")*(",$string);
}
return $string;
}
但我相信这可以做得更好与preg_replace或其他一些正则表达式函数?但是我觉得那些手册实在是太麻烦了。
让我们从你要找的开始:
- 以下任意一个:(
(a|b)
将匹配a
或b
)- 任意数字,
'd
字符
)
:')
- 任意数字,
(
: '(
创建这个模式:('d|'))'(
。但是由于您想修改字符串并保留这两个部分,您可以将'(
分组,这导致('()
使其更难以读取,但更易于处理。
现在剩下的一切都是告诉如何重新排列,这很简单:''1*''2
,留下这样的代码
$regex = "/('d|'))('()/";
$replace = "''1*''2";
$new = preg_replace($regex, $replace, $test);
要查看模式实际上匹配所有情况,请参见以下示例:
要识别任何后跟(
或 )(
的组合并在它们之间放置星号,您可以使用look - around断言的组合。
echo preg_replace("/
(?<=[0-9)]) # look behind to see if there is: '0' to '9', ')'
(?='() # look ahead to see if there is: '('
/x", '*', '(4+3(4-2)-3)(2+3)');
Positive Lookbehind断言前面的是数字或右括号。而正向向前看则断言前面的字符后跟一个左括号。
另一个选择是使用'K
转义序列来代替Lookbehind。'K
重置上报匹配的起始点。任何先前消耗的字符都不再包括在内(将丢弃到此为止匹配的所有内容)。
echo preg_replace("/
[0-9)] # any character of: '0' to '9', ')'
'K # resets the starting point of the reported match
(?='() # look ahead to see if there is: '('
/x", '*', '(4+3(4-2)-3)(2+3)');
你的php代码应该是,
<?php
$mystring = "4+3(4-2)-(5)(3)";
$regex = '~'d+'K'(~';
$replacement = "*(";
$str = preg_replace($regex, $replacement, $mystring);
$regex1 = '~')'K'(~';
$replacement1 = "*(";
echo preg_replace($regex1, $replacement1, $str);
?> //=> 4+3*(4-2)-(5)*(3)
解释:
-
~'d+'K'(~
这将匹配后跟(
的一个或多个数字。因为'K,它排除了'd+ - 再次将匹配的部分替换为
*(
,进而产生3*(
,结果存储在另一个变量中。 -
')'K'(
匹配)(
,不包括第一个)
。这将被*(
所取代,进而产生)*(
愚蠢的方法:^)
$value = '4+3(4-2)(1+2)';
$search = ['1(', '2(', '3(', '4(', '5(', '6(', '7(', '8(', '9(', '0(', ')('];
$replace = ['1*(', '2*(', '3*(', '4*(', '5*(', '6*(', '7*(', '8*(', '9*(', '0*(', ')*('];
echo str_replace($search, $replace, $value);