如何解决将数学表达式拆分为数组而不拆分括号和单引号之间的子表达式
假设我有这个字符串:
1 + 2 * (3 + (23 + 53 - (132 / 5) + 5) - 1) + 2 / 'test + string' - 52
我想将其拆分为运算符和非运算符数组,但不得拆分 ()
和 '
之间的任何内容。
我希望输出是:
[1,"+",2,"*","(3 + (23 + 53 - (132 / 5) + 5) - 1)","/","'test + string'","-",52]
我正在使用此代码:
preg_split("~['\(][^'()]*['\)](*SKIP)(*F)|([+\-*/^])+~",$str,-1,PREG_SPLIT_DELIM_CAPTURE);
该技术对运算符和 '
执行我想要的操作,但不适用于 ()
。但是它只保留 (132 / 5)
(最深的嵌套括号表达式)并拆分所有其他表达式,给我这个输出:
[1,"(3","(23",53,"(132 / 5)","5)","1)",52]
如何确保最外面的括号表达式及其所有内容保持在一起?
解决方法
您可以使用模式递归匹配平衡括号的第一个子模式,然后使用 SKIP FAIL。更改后,您仍然可以使用捕获组,该组将是组 2,并且由于 PREG_SPLIT_DELIM_CAPTURE
标志,这些值将被保留。
要删除空条目,您可以添加 PREG_SPLIT_NO_EMPTY
标志。
(?:(\((?:[^()]++|(?1))*\))|'[^']*')(*SKIP)(*F)|([+\-*/^])
$str = "1 + 2 * (3 + (23 + 53 - (132 / 5) + 5) - 1) + 2 / 'test + string' - 52";
$result = preg_split("~(?:(\((?:[^()]++|(?1))*\))|'[^']*')(*SKIP)(*F)|([+\-*/^])~",$str,-1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($result);
输出
Array
(
[0] => 1
[1] => +
[2] => 2
[3] => *
[4] => (3 + (23 + 53 - (132 / 5) + 5) - 1)
[5] => +
[6] => 2
[7] => /
[8] => 'test + string'
[9] => -
[10] => 52
)
,
我确实喜欢 @thefourthbird 的递归子模式,但我更喜欢标准化输出元素,以便删除所有空格。
我不会使用分隔符捕获或跳过失败,但完整字符串重新启动 (\K
) 以省略空格。
代码:(Demo)
preg_split(
"~(?:(\((?:[^()]+|(?1))*\))|'[^']*'|[\d.]+|[*/^+-])\K ?~",PREG_SPLIT_NO_EMPTY
)
我已经在 SO 上完成了 similar 技术,就像这样。另一个考虑是:您希望如何处理有符号数字?数字实体应该保留符号符号还是应该像运算符一样将其分开?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。