You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java如何用正则拆分字符串,将运算符与标识符分开用于BNF解释器

我正在为巴科斯范式(Backus Naur Form)文法编写解释器,对应文法规则如下:

<statement> ::= <assignment> | "PRINT" "(" <expression> ")"
<assignment>    ::= <variable> = <expression>
<expression>    ::= <term> <expression*>
<expression*>   ::= "+" <expression> | "-" <expression> | ""
<term>  ::= <factor> <term*>
<term*> ::= "*" <term> | "/" <term> | ""
<factor>    ::= <number> | <variable> | "(" <expression> ")"
<variable>  ::= <lowercase> <variable*>
<variable*> ::= <variable> | ""
<number>    ::= <digit> <number*>
<number*>   ::= <number> | ""

现在需要编写代码判断输入字符串是否为合法表达式,最初的思路是使用split方法拆分字符串,分离所有独立的单词和符号,最初写法为:

String[] words = line.split("\\s+");

这种写法可以把String line = "y = x + 12 * z"这类带空格的字符串正确拆分为["y", "=", "x", "+", "12", "z"],但当输入无空格的表达式比如String line = "x=12+z"时,拆分结果为["x=12+z"],无法正常拆分。

需求是拆分时将+、-、*、/、=、(、)这些符号都单独作为数组的一项。比如输入String line = "x = z+12 * y -(z *var )"时,拆分结果为["x", "=", "z", "+", "12", "*", "y", "-", "(", "z", "*","var", ")"]。


解决方案

使用带环视规则的正则表达式即可实现需求,代码如下:

// 拆分规则:空格、符号前置位置、符号后置位置
String[] words = line.split("\\s+|(?=[+\\-*/=()])|(?<=[+\\-*/=()])");
// 过滤可能出现的空字符串(比如输入开头/结尾是符号的场景)
words = Arrays.stream(words).filter(item -> !item.isEmpty()).toArray(String[]::new);

正则规则说明

  • \\s+:匹配1个或多个空格,作为拆分边界,拆分后自动丢弃空格
  • (?=[+\\-*/=()]):正向零宽断言,匹配运算/分隔符号的前方位置,确保符号被单独拆分出来
  • (?<=[+\\-*/=()]):反向零宽断言,匹配运算/分隔符号的后方位置,确保符号前后的内容和符号本身分离

上述代码测试你给出的示例输入,输出结果完全符合要求。


内容的提问来源于stack exchange,提问作者ParkerHarrelson123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 20:27:03