Java 用正则表达式解析复系数多项式
作为计算方阵Jordan标准形个人项目的一部分,我需要解析复系数多项式,以简化大量代码 (职位底部的相关代码) 我想分析的多项式的形式如下:Java 用正则表达式解析复系数多项式,java,regex,parsing,polynomials,Java,Regex,Parsing,Polynomials,作为计算方阵Jordan标准形个人项目的一部分,我需要解析复系数多项式,以简化大量代码 (职位底部的相关代码) 我想分析的多项式的形式如下: 系数可以是实系数、虚系数或复系数 如果系数是复杂的,它将用括号括起来。如果这些括号是前导系数,则它们前面不会有+或- 如果系数是实数、虚数或复数,其实部和/或虚部分量的大小为1,则1不会出现,而只会出现符号 括号前只能加+ 变量x可能有一个幂(>2),可能有一个1的幂,然后它会像x一样出现,或者根本不会出现 关于多项式的文本表示没有更多的规则,即幂不一定按
+
或-
1
不会出现,而只会出现符号+
x
可能有一个幂(>2
),可能有一个1的幂,然后它会像x
一样出现,或者根本不会出现1
-1
-2.1x
3i
x^2-1
-x^3+2x+1
(5-5i)x^2-x-1
(-1+i)x-5
-ix^3-x^2+1
(引导不必要的1x
)1
(括号有一个前导+(+1-2i)x
,实组件有一个前导+
)+
(因为系数是虚构的,所以不需要括号)(5.1i)x^2
(复系数有前导-(i-1)
)-
assertEquals(“多项式解析不正确”,poly07,PolyParser.parse(exp07))代码>
其中poly07
如下所示:(5-5i)x^2-x-1
这是提出的例外情况:
java.lang.NumberFormatException: For input string: "5-5"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at PolyParser.parse(PolyParser.java:55)
at PolyParserTest.testParse(PolyParserTest.java:59)
我试过调试,发现正则表达式捕获了5-5i
(后来去掉了I
)。然后,它尝试使用参数字符串5-5
调用Double.parseDouble
,这会导致异常
在阅读了所有的内容之后,我不太明白为了让整个节目正常运行,正则表达式中需要做哪些调整。
此外,正则表达式不像上面提到的表示约束那样有序,因为我想在尝试将其解析为实之前看看系数是否复杂;还遇到了将实数(即小数点)解析为整数的问题,这就是正则表达式首先处理实数的原因
正则表达式:
public static final String POLYNOMIAL_REGEX =
"([+-])?" + // leading plus or minus
"(\\()?" + // parenthesis to denote the beginning of a complex number
"([+-])?(((\\d+.\\d+)|\\d+)i)?" + // component of coefficient, imaginary
"(((-)?\\d+.\\d+)|\\d+)?" + // component of coefficient, real
"(\\))?" + // parenthesis to denote the end of a complex number
"(x)?" + // variable
"(?:\\^(\\d+))?"; // power of the variable
我不打算在这里发布所有相关的代码,因为它会把东西弄得乱七八糟。所有代码都已打开,只需确保切换到分支PolyParser
相关代码在以下文件中:
PolyParser.java
polymonent.java
Complex.java
测试单元位于文件PolyParserTest.java
中,正则表达式基本上无法解析表达式,因为它们无法跟踪嵌套(例如,括号)。这是一个大多数人都不知道的教训,他们通过艰难的方式发现了这一点
但是,表达式很容易解析,使用自顶向下的解析。请参阅我关于如何执行此操作的答案:此答案涵盖了如何进行解析,并链接到另一个关于如何构建AST来表示表达式的答案
第一步:写一个语法,表示你的表达式将允许什么。你的问题中有一个特别的描述,但语法会迫使你准确地写出什么是合法的,什么是不合法的。使用这种语法,您可以非常轻松地编写上面建议的递归下降解析器。正则表达式几乎从来都不是解析问题的正确解决方案。我的建议是:不要。使用上下文无关的解析器,如果您想要一个简单的解析器,请查看。或者你可以全力以赴,使用像Antlr这样的东西。或者,你可以尝试一下,这一切都是开箱即用的,你甚至可以直接计算多项式。首先你要弄清楚你需要做什么。然后你选择必要的工具来做这件事。在这种情况下,您首先选择了工具。。。这是错误的假设,假设用户输入了正确格式的表达式,我们就放弃了防御性编程。这样,就没有嵌套的括号。我使用正则表达式及其捕获组作为解析器。当我手头上有一个几乎可以按我所希望的方式工作的正则表达式时,从零开始实现解析器似乎需要进行大量的研究和工作,只是缺少一些微调。你的想法?你的用户会在输入公式时出错。不管你喜欢与否,他们都会使用括号,你需要一个健壮的解析器。