简体   繁体   中英

How to split a string using regex, taking numbers with more of 1 digits #Java

This program should be a calculator, so when the user insert a string like "6+9-2+4-12", it should give the result... The program does it right when the user gives only one-digit number like "6+2-1+3-2"; but if the user insert a 2-digit number like "12", the program consider it like 1 & 2.

This is the regex i used:

String[] somma = text1.split("(?<=[0-9]+)");

And this is the result of the expression "6+9-2+4-12":

6 + 9 - 2 + 4 - 1 2
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "+"
at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.base/java.lang.Double.parseDouble(Double.java:549)
at Calcolatrice.Ascoltatore.actionPerformed(Ascoltatore.java:69)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6636)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
at java.desktop/java.awt.Component.processEvent(Component.java:6401)
at java.desktop/java.awt.Container.processEvent(Container.java:2263)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5012)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4919)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4548)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4489)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2764)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

It should work because it takes numbers [0-9] of more digits with "+"... I don't know what to do anymore

One interpretation of the question is that you want to keep digits together, but split everything else into separate tokens, so you want to split:

  • After a digit
  • Before a digit
  • Not between digits

As independent rules, that would be:

  • After a digit that is not followed by a digit: (?<=\\d)(?!\\d)
  • Before a digit is not preceded by a digit: (?<!\\d)(?=\\d)

So what you want is:

String[] somma = text1.split("(?<=\\d)(?!\\d)|(?<!\\d)(?=\\d)");

To not get an empty token at the beginning, we don't want to split "before a digit that is at the beginning of input", so we add that exact condition:

String[] somma = text1.split("(?<=\\d)(?!\\d)|(?<!\\d|^)(?=\\d)");
// result: ["6", "+", "9", "-", "2", "+", "4", "-", "12"]

This will allow evaluating an expression consisting of all operators, incl. parentheses, depending on the code that uses the result of this tokenization of the input expression.


Another interpretation of the question, based on the attempted split in the question, is that you only want to split after digits, so you want to split:

  • After a digit
  • Not between digits

That is of course even simpler:

String[] somma = text1.split("(?<=\\d)(?!\\d)");
// result: ["6", "+9", "-2", "+4", "-12"]

This will allow evaluating an expression consisting of only + and - operators, by simply parsing and adding the values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM