I have a php code as shown below which validates the answer at Line A which user enters in a html form.
When user enters any answer with apostrophe in the html input field form, I am getting the error message Secret Answer is Invalid.
For example: On entering Hello World', I am getting the error message Secret Answer is Invalid from Line Z.
//response
$response_error = new error();
$response_error->field = SECRET_response;
if($response != "" && $service->validAnswer($answer) != 'true'){ // Line A
$response_error->inError = true;
$response_error->errorMessage = SECRET_response.ISINVALID; // Line Z
} else {
$response_error->inError = false;
}
The Java code/method belonging to the validAnswer method used at Line A above is:
public static boolean validAnswer(String answer) {
Pattern a = Pattern.compile("^(?=.*\\S)[a-zA-Z0-9éèàêâçîëïÇÉÔÂÊÎÔÛËÏÀùÙ!#%&$%*\\- ]+$"); // Line B
Matcher b = a.matcher(answer);
logger.info("validAnswer: mmatches(): " + (b.matches()) + " a: " + a);
return b.matches();
}
Problem Statement:
I am wondering what changes I need to make in the java code above so that it takes apostrophe in the html input form.
This is what I have tried in the Java code:
I have put ' in at the end of [ ] inside of it. On trying that, it doesn't seem to work.
public static boolean validAnswer(String answer) {
Pattern a = Pattern.compile("^(?=.*\\S)[a-zA-Z0-9éèàêâçîëïÇÉÔÂÊÎÔÛËÏÀùÙ!#%&$%*\\-' ]+$"); // Line A
Matcher b = a.matcher(answer);
logger.info("validAnswer: mmatches(): " + (b.matches()) + " a: " + a);
return b.matches();
}
Calling Java from PHP just to use a regex is very weird and inefficient. PHP has regex support of course, so you don't need Java for that.
Anyway, your latest code works perfectly:
import java.util.regex.*;
public class Test
{
public static boolean validAnswer(String answer)
{
Pattern a = Pattern.compile("^(?=.*\\S)[a-zA-Z0-9éèàêâçîëïÇÉÔÂÊÎÔÛËÏÀùÙ!#%&$%*\\-' ]+$");
Matcher b = a.matcher(answer);
return b.matches();
}
public static void main(String args[])
{
System.out.println(validAnswer("Hello World'"));
}
}
Output:
true
So I guess you didn't recompile your code after modifying it.
Related
im trying to do string .contains() for specific lines on text
im reading in lines of a file using Files.readAlllines.
im trying to do
Path c1=Paths.get(prop.getProperty("testPWP"));
List<String> newLines1 = new ArrayList<String>();
for (String line : Files.readAllLines(c1, StandardCharsets.UTF_8)) {
if (line.contains("return test ;\r\n" + " }")) {
newLines1.add( line.replace("return test ;\r\n" +
" }", "return test ;\r\n" +
" }*/"));
}
else {
newLines1.add(line);
}
}
Files.write(c1, newLines1, StandardCharsets.UTF_8);
im basically trying to comment the } after the return statement but the contains function not recongnizing it as its in new line in the file.
Any help on this issue?
As you may have noticed, Files.readAllLines reads all lines and returns a list in which each string represents a line. To accomplish what you are trying to do, you either need to read the entire file into a single string, or concatenate the strings you already have, or change your approach of substitution. The easiest way would be to read the entire contents of the file into one string, which can be accomplished as follows:
String content = new String(Files.readAllBytes(Paths.get("path to file")));
or if you are using Java 11 or higher:
String content = Files.readString(Paths.get("path to file"));
You can use the replaceable parameter to replace the regex.
Demo:
public class Main {
public static void main(String[] args) {
String find = "return test ;\r\n" + " }";
String str = "Hello return test ;\r\n" + " } Hi Bye";
boolean found = str.contains(find);
System.out.println(found);
if (found) {
str = str.replaceAll("(" + find + ")", "/*$1*/");
}
System.out.println(str);
}
}
Output:
true
Hello /*return test ;
}*/ Hi Bye
Here $1 specifies the capturing group, group(1).
In your program, the value of str can be populated as follows:
String str = Files.readString(path, StandardCharsets.US_ASCII);
In case your Java version is less than 11, you do it as follows:
String str = new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.US_ASCII);
I'm solving this problem:
problem
And what I did is this:
import java.io.*;
import static java.lang.System.exit;
import java.util.*;
//Driver for Abbreviations
public class AbbreviationsDriver {
//string of message
private static String message = "";
//List of Abbreviations
private static String[] AbbreviationsList;
//Abbreviations list file
private static File AbbreviationsListFile = new File("abbreviations.txt");
//message file
private static File inputMessageFile = new File("sample_msg.txt");
//output message file
private static File outputMessageFile = new File("sample_output.txt");
//main method
public static void main(String[] args) throws FileNotFoundException {
setAbbreviations(readFileList(AbbreviationsListFile));
System.out.println("list of abbriviations:\n" + Arrays.toString(AbbreviationsList));
setMessage(readFile(inputMessageFile));
System.out.println("\nMessage in input file:\n" + message);
writeFile(outputMessageFile,addTags(message, AbbreviationsList));
System.out.println("\nMessage with tag in output file:\n" + addTags(message, AbbreviationsList));
}
//method to add tags
public static String addTags(String toTag, String[] abbreviations){
for(String abbreviation:abbreviations)
if(toTag.contains(abbreviation)){
toTag = toTag.replaceAll(abbreviation, "<" + abbreviation + ">");
}
return toTag;
}
//method to read the file list
public static String[] readFileList(File fileInput){
String input = "";
try{
Scanner inputStream = new Scanner(fileInput);
while(inputStream.hasNextLine()){
input = input + inputStream.nextLine()+ "<String>";
}
inputStream.close();
// System.out.println("list in string: " + input);
return input.split("<String>");
}
catch(Exception exception){
System.out.println("error in getting string array from file:\t" + exception.getMessage());
exit(0);
return new String[] {""};
}
}
//method to read the file
public static String readFile(File fileInput){
String inputFile = "";
try{
Scanner inputStatement = new Scanner(fileInput);
while(inputStatement.hasNextLine()){
inputFile = inputFile + inputStatement.nextLine();
}
inputStatement.close();
return inputFile;
}
catch(Exception exception){
System.out.println("error in getting message from file:\t" + exception.getMessage());
exit(0);
return "";
}
}
//method to write the output file
public static void writeFile(File fileName, String outString){
try{
PrintWriter outputStatement = new PrintWriter(fileName);
outputStatement.print(outString);
outputStatement.close();
}
catch(Exception exception){
System.out.println("error in setting message of file:\t" + exception.getMessage());
exit(0);
}
}
//method to set abbreviations
public static void setAbbreviations(String[] newAbbreviationsList){
AbbreviationsList = newAbbreviationsList;
}
//setter to set message
public static void setMessage(String newMessage){
message = newMessage;
}
//input string
public static String inputString(){
return new Scanner(System.in).nextLine();
}
}
abbreviations.txt is here:
lol
:)
iirc
4
u
ttfn
and sample_msg.txt is here:
How are u today? Iirc, this is your first free day. Hope you are having fun! :)
but when I compile and run, the error message comes out:
list of abbriviations:
[lol, :), iirc, 4, u, ttfn]
Message in input file:
How are u today? Iirc, this is your first free day. Hope you are having fun! :)
Exception in thread "main" java.util.regex.PatternSyntaxException: Unmatched closing ')' near index 0
:)
^
at java.util.regex.Pattern.error(Pattern.java:1969)
at java.util.regex.Pattern.compile(Pattern.java:1706)
at java.util.regex.Pattern.<init>(Pattern.java:1352)
at java.util.regex.Pattern.compile(Pattern.java:1028)
at java.lang.String.replaceAll(String.java:2223)
at AbbreviationsDriver.addTags(AbbreviationsDriver.java:44)
at AbbreviationsDriver.main(AbbreviationsDriver.java:36)
Process finished with exit code 1
I don't know how to solve this error because I've never seen this error before.
Please help me!
You pass wrong parameter into replaceAll(). First parameter must be a regex. For your purpose, regex is not needed, so use replace() method instead.
You faced the error because ) is treated as a metacharacter in regex and therefore either it needs to be escaped or must be paired with its closing counterpart.
Solution
You need to treat abbreviations with metacharacters and strings without metacharacters differently. For strings with metacharacters (e.g. :) where ) is a metacharacter), you should use String#replace while for the strings without metacharacter you should use String#replaceAll.
When you use String#replaceAll, you should create a capturing group which includes word boundaries e.g. (\bu\b) so that only those u will be processed which appear as a word. Finally, you should replace the capturing group with <$1> where $1 refers to the first (in the code given below, there is only one capturing group) capturing group e.g. (\bu\b) will be replaced by <u>.
Demo:
public class Main {
public static void main(String[] args) {
String[] abbrWithoutMetaChars = { "lol", "iirc", "4", "u", "ttfn" };
String[] abbrWithMetaChars = { ":)" };
// Test string
String str = "How are u today? iirc, this is your first free day. Hope you are having fun! :)";
// Replace all abbr. without meta chars
for (String abbreviation : abbrWithoutMetaChars) {
str = str.replaceAll("(\\b" + abbreviation + "\\b)", "<$1>");
}
// Replace all abbr. with meta chars
for (String abbreviation : abbrWithMetaChars) {
str = str.replace(abbreviation, "<" + abbreviation + ">");
}
System.out.println(str);
}
}
Output:
How are <u> today? <iirc>, this is your first free day. Hope you are having fun! <:)>
The problem is actually tricky. For example, in the list of abbreviations, u should be interpreted as a word and not a letter, since in your expected output you don't surround the letter u in the word your with angle brackets but only the u that appears by itself. Hence your code needs to locate the abbreviation as a single word in the input.
Also, iirc appears in the abbreviations list but in the input you have Iirc (with a capital I) and in the expected output it should appear as <Iirc> and not as <iirc>. In other words you should ignore case when locating the abbreviation but you need to keep the case after surrounding the abbreviation with angle brackets.
Then you have :) in the abbreviations list but ) has special meaning in regular expression syntax so your code also needs to handle that situation.
All the above implies that you need to analyze the contents of the abbreviations list file in order to turn a raw abbreviation into a valid regular expression that you can then use to locate the abbreviation in the input text.
If you assume that the abbreviations list may contain every possible abbreviation, you would probably need a large amount of code to handle each one properly. Rather than do that, I just concentrated on your sample list which divides easily into two groups:
simple words
punctuation only
Note that the second group is also known as emoticons and some emoticons contain both letters and punctuation which my code, below, does not handle. As I said, my solution only pertains to your sample list of abbreviations.
Here is the code and below the code are some notes regarding it. Please not that I took the liberty of not just fixing your code, but refactoring it as well.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
//Driver for Abbreviations
public class AbbreviationsDriver {
//Abbreviations list file
private static Path abbreviationsListPath = Paths.get("abbreviations.txt");
//message file
private static Path inputPath = Paths.get("sample_msg.txt");
//output message file
private static File outputMessageFile = new File("sample_output.txt");
//main method
public static void main(String[] args) throws FileNotFoundException {
List<String> abbreviationsList = readFileList(abbreviationsListPath);
System.out.println("List of abbreviations: " + abbreviationsList);
String message = readFile(inputPath);
System.out.println("\nMessage in input file:\n" + message);
String result = addTags(message, abbreviationsList);
writeFile(outputMessageFile, result);
System.out.println("\nMessage with tag in output file:\n" + result);
}
//method to add tags
public static String addTags(String toTag, List<String> abbreviations) {
for (String abbreviation : abbreviations) {
String regex;
if (abbreviation.contains(")")) {
regex = "(\\Q" + abbreviation + "\\E)";
}
else {
regex = "(?i)(\\b" + abbreviation + "\\b)";
}
toTag = toTag.replaceAll(regex, "<$1>");
}
return toTag;
}
//method to read the file list
public static List<String> readFileList(Path path) {
List<String> list;
try {
list = Files.readAllLines(path);
}
catch (IOException exception) {
list = List.of();
System.out.println("Failed to load: " + path);
exception.printStackTrace();
}
return list;
}
//method to read the file
public static String readFile(Path path) {
String inputFile;
try {
inputFile = Files.readString(path);
}
catch (IOException exception) {
System.out.println("Failed to read: " + path);
exception.printStackTrace();
inputFile = "";
}
return inputFile;
}
//method to write the output file
public static void writeFile(File fileName, String outString) {
try {
PrintWriter outputStatement = new PrintWriter(fileName);
outputStatement.print(outString);
outputStatement.close();
}
catch (Exception exception) {
System.out.println("Failed to write file: " + fileName);
exception.printStackTrace();
}
}
}
I use interface Path rather that class File so that I can use methods of class Files to read the text files that contain the abbreviations list and the input. Hence my code works with interface List rather than with an array of String.
Passing class members to methods as method parameters defeats the purpose of having a class member in the first place. Hence I removed the members message and AbbreviationsList.
The actual work of locating the abbreviations in the input and surrounding them with angle brackets, all occurs in method addTags. Here I handle each separate group of abbreviations. If the abbreviation contains the character ), I quote it by surrounding it with quote markers \Q and \E. (Refer to javadoc of class Pattern). Otherwise the abbreviation is a regular word, so I surround it with the word boundary marker \b. I also enclose each regular expression in parentheses so as to make it a capturing group. Note that the second regular expression begins with (?i) which means to ignore case. Hence iirc will match Iirc.
The replacement string is <$1>. The $1 is replaced with the string that was actually matched so any abbreviation found in the input will be replaced by the matched string surrounded with angle brackets.
Finally, here is the output when running the above code and using your sample data.
List of abbreviations: [lol, :), iirc, 4, u, ttfn]
Message in input file:
How are u today? Iirc, this is your first free day. Hope you are having fun! :)
Message with tag in output file:
How are <u> today? <Iirc>, this is your first free day. Hope you are having fun! <:)>
There are several ways to do this. Either you use regular expressions, or you do things the old-fashioned way by parsing word-by-word. Others have pointed out problems with your current code, due to using strings that contain regular expression metacharacters. In particular,
String doesNotWork = "I am :)".replaceAll(":)", "happy"); // invalid regex
This can be solved by quoting the string, so that metacharacters are converted into literals (it returns the string that would be written as "\\Q:)\\E", because \Q and \E are used as delimiters for quoting whole substrings, as opposed to \, which quotes the next only if it is non-alphabetical; and is otherwise used for a host of regex classes):
String worksAsExpected = "I am :)".replaceAll(Pattern.quote(":)"), "happy");
The most efficient way to process text is to do a single pass. This can be achieved by combining literal expressions with |s:
String regex = Stream.of("lol iirc 4".split(" "))
.map(s -> Pattern.quote(s)) // quotes each emoticon
.collect(Collectors.joining("|")); // joins with |
Matcher m = Pattern.compile(regex).matcher(input);
This yields surprisingly compact code, with nothing hardcoded. Finished code:
import java.util.regex.*;
import java.util.stream.*;
public class T {
public static String mark(
String[] needles, String startMark, String endMark, String input) {
String regex = Stream.of(needles)
.map(s -> s.matches("\\p{Alpha}+") ? // quotes each
"\\b" + Pattern.quote(s) + "\\b" : // to avoid yo<u>r
Pattern.quote(s)) // to handle emoticons
.collect(Collectors.joining("|")); // joins with |
Matcher m = Pattern.compile(regex).matcher(input);
StringBuffer output = new StringBuffer();
while (m.find()) {
m.appendReplacement(output, startMark + m.group() + endMark);
}
m.appendTail(output);
return output.toString();
}
public static void main(String ... args) {
System.out.println(mark(
"lol iirc 4 u ttfn :)".split(" "), // abbreviations
"<", ">", // markers to mark them with
"How are u today? iirc, this is your first free day. "
+ "Hope you are having fun! :)"));
}
}
I used #Arvind's trick of placing word-boundary metacharacters (\\b) only on alphabetical needles. This fixes all us in words being marked; but may yield strange results for 4s: writing a number with 4s in it will get it marked. Ultimately, natural language processing is hard. Regular expressions are great for very regular inputs.
This question already has answers here:
Split string on spaces in Java, except if between quotes (i.e. treat \"hello world\" as one token) [duplicate]
(1 answer)
Tokenizing a String but ignoring delimiters within quotes
(14 answers)
Closed 6 years ago.
Hi I am new to Java and trying to use the split method provided by java.
The input is a String in the following format
broadcast message "Shubham Agiwal"
The desired output requirement is to get an array with the following elements
["broadcast","message","Shubham Agiwal"]
My code is as follows
String str="broadcast message \"Shubham Agiwal\"";
for(int i=0;i<str.split(" ").length;i++){
System.out.println(str.split(" ")[i]);
}
The output I obtained from the above code is
["broadcast","message","\"Shubham","Agiwal\""]
Can somebody let me what I need to change in my code to get the desired output as mentioned above?
this is hard to split string directly.So, i will use the '\t' to replace
the whitespace if the whitespace is out of "". My code is below, you can try it, and maybe others will have better solution, we can discuss it too.
package com.code.stackoverflow;
/**
* Created by jiangchao on 2016/10/24.
*/
public class Main {
public static void main(String args[]) {
String str="broadcast message \"Shubham Agiwal\"";
char []chs = str.toCharArray();
StringBuilder sb = new StringBuilder();
/*
* false: means that I am out of the ""
* true: means that I am in the ""
*/
boolean flag = false;
for (Character c : chs) {
if (c == '\"') {
flag = !flag;
continue;
}
if (flag == false && c == ' ') {
sb.append("\t");
continue;
}
sb.append(c);
}
String []strs = sb.toString().split("\t");
for (String s : strs) {
System.out.println(s);
}
}
}
This is tedious but it works. The only problem is that if the whitespace in quotes is a tab or other white space delimiter it gets replaced with a space character.
String str = "broadcast message \"Shubham Agiwal\" better \"Hello java World\"";
Scanner scanner = new Scanner(str).useDelimiter("\\s");
while(scanner.hasNext()) {
String token = scanner.next();
if ( token.startsWith("\"")) { //Concatenate until we see a closing quote
token = token.substring(1);
String nextTokenInQuotes = null;
do {
nextTokenInQuotes = scanner.next();
token += " ";
token += nextTokenInQuotes;
}while(!nextTokenInQuotes.endsWith("\""));
token = token.substring(0,token.length()-1); //Get rid of trailing quote
}
System.out.println("Token is:" + token);
}
This produces the following output:
Token is:broadcast
Token is:message
Token is:Shubham Agiwal
Token is:better
Token is:Hello java World
public static void main(String[] arg){
String str = "broadcast message \"Shubham Agiwal\"";
//First split
String strs[] = str.split("\\s\"");
//Second split for the first part(Key part)
String[] first = strs[0].split(" ");
for(String st:first){
System.out.println(st);
}
//Append " in front of the last part(Value part)
System.out.println("\""+strs[1]);
}
Here i want to validate filename using regex in java. i implemented below code but this is not works for me for 3rd type file.
Can i check prefix and extenstion in regex ???
My validate filename looks like these 3 ways
1) prefix_digit.digit.extenstion example : AB_1.1.fuij (Here fuij is my extension)
2) prefix_digit.digit.digit.extenstion example : AB_1.1.1.fuij
3) prefix_digit.digit.B/P.digit.extensionexample : AB_1.1.B.1.fuij
Only these 3 types of file valid. 3rd one is beta and pilot version files. if beta and pilot version file is there than is should be like this which i mentioned above
I am going to write some valid and invalid files
**Valid :**
AB_1.1.fuij
AB_1.4.fuij
AB_1.1.1.fuij
AB_1.1.B.1.fuij
AB_3.4.P.7.fuij
***Invalid :***
AB_0.1.fuij
AB_1.B.1.1.fuij(B/P should be place on 3rd always)
AB_1.2.B.0.fuij
CODE :
import java.util.ArrayList;
import java.util.regex.Pattern;
public class democlass {
/**
* Test harness.
*/
public static void main(String[] args) {
ArrayList<String> demoversion = new ArrayList<String>();
System.out.println("Result >>>>>>>>>>>> "
+isFileValid("AB_1.1.fuij"));
System.out.println("Result >>>>>>>>>>>> "
+isFileValid("AB_1.B.fuij"));
System.out.println("Result >>>>>>>>>>>> "
+isFileValid("AB_1.1.1.fuij"));
System.out.println("Result >>>>>>>>>>>> "
+isFileValid("AB_1.P.1.1.fuij"));
System.out.println("Result >>>>>>>>>>>> "
+isFileValid("AB_1.1.B.1.fuij"));
}
private static boolean isFileValid(String input)
{
String regexFinalBugFix = "^\\d+\\.\\d+\\.\\d+$";
String regexFinal = "^\\d+\\.\\d+$";
String regexBetaPilot = "^\\d+\\.\\d+\\.\\[BP]+\\.\\d+$";
final Pattern pattern1 = Pattern.compile(regexFinal);
final Pattern pattern2 = Pattern.compile(regexBetaPilot);
final Pattern pattern3 = Pattern.compile(regexFinalBugFix);
String inputVersion = null;
int suffixIndex = input.lastIndexOf(".");
int prefixIndex = input.lastIndexOf("_");
if (suffixIndex > 0 && prefixIndex > 0) {
inputVersion = input.substring(prefixIndex + 1,
suffixIndex);
String prefixString1 = input.substring(0, 3);
String suffixString1 = input.substring(suffixIndex);
if(prefixString1.equals("AB_") && suffixString1.equals(".fuij"))
{
if (pattern1.matcher(inputVersion).matches()
|| pattern2.matcher(inputVersion).matches()
|| pattern3.matcher(inputVersion).matches()) {
return true;
}
return false;
}
return false;
}
return false;
}
}
OUTPUT :
Result >>>>>>>>>>>> true
Result >>>>>>>>>>>> false
Result >>>>>>>>>>>> true
Result >>>>>>>>>>>> false
Result >>>>>>>>>>>> false : It should be valid but it is false, why??
Your regexBetaPilot is wrong: you are escaping the opening bracket of the [BP] class. Try this instead:
String regexBetaPilot = "^\\d+\\.\\d+\\.[BP]+\\.\\d+$";
You can easily combine all three patterns into a single pattern:
String regex = "\\d+\\.(\\d+\\.([BP]+\\.)?)?\\d+";
You don't need the anchors (^ and $). Since you are using matches() instead of find(), it will always try to match the entire string.
EDIT I left in the + after [BP] because that's what you had in your original code. However, if you want to match a single B or P, then you should remove the + from the pattern.
You are escaping the opening bracket of [BP], so it tries to find a [ in the string.
This works:
String regexBetaPilot = "^\\d+\\.\\d+\\.[BP]+\\.\\d+$";
Something like this should work with AB being static:
Regular Expression: AB_\d+\.\d+((\.\d){0,1}|\.[BP]\.\d+)\.fuij
as a Java string AB_\\d+\\.\\d+((\\.\\d){0,1}|\\.[BP]\\.\\d+)\\.fuij
This misses two of your listed invalids, but I was unsure why they should be invalid. I can halep more if you explain the rules for success / failure better?
You can simplify your regular expression to
AB_\d+\.\d+(?:(?:\.[BP])?\.\d+)?\.fuij
This matches AB_digits.digits. Then comes an optional .digits, .B.digits or .P.digits. And finally matches .fuij. From your examples, there might be only a single B or P. If you wish to match multiple Bs and Ps, just add the + again.
And then your isFileValid() function might be reduced to
private static boolean isFileValid(String input)
{
final String re = "AB_\\d+\\.\\d+(?:(?:\\.[BP])?\\.\\d+)?\\.fuij";
final Pattern pattern = Pattern.compile(re);
return pattern.matcher(input).matches();
}
I am working on a homework assignment, and I am going a little "above and beyond" what is called for by the assignment. I am getting a run-time error in my code, and can not for the life of me figure out what it is that I have done wrong.
Here is the assignment:
Write a program that displays a simulated paycheck. The program should ask the user to enter the date, the payee’s name, and the amount of the check. It should then display a simulated check with the dollar amount spelled out.
Here is my code:
CheckWriter:
/* CheckWriter.java */
// Imported Dependencies
import java.util.InputMismatchException;
import java.util.Scanner;
public class CheckWriter {
public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
// Try to get the name
String name = "";
NameValidator validateName = new NameValidator();
while (validateName.validate(name) == false) {
System.out.println("Enter the name: ");
name = keyboard.nextLine();
if (validateName.validate(name) == false) {
System.out.println("Not a valid name.");
}
}
// Get the date
String date = "";
DateValidator validateDate = new DateValidator();
while (!validateDate.validate(date)) {
System.out.println("Enter the date (dd/mm/yyyy): ");
date = keyboard.nextLine();
if (!validateDate.validate(date)) {
System.out.println("Not a valid date.");
}
}
// Try to get the amount of the check
String checkAmount = "";
CurrencyValidator validateCurrency = new CurrencyValidator();
while (!validateCurrency.validate(checkAmount)) {
System.out.print("Enter the Check Amount (XX.XX): $");
checkAmount = keyboard.nextLine();
if (!validateCurrency.validate(checkAmount)) {
System.out.println("Not a valid check amount.");
}
}
String checkWords = checkToWords(checkAmount); // ERROR! (48)
System.out
.println("------------------------------------------------------\n"
+ "Date: "
+ date
+ "\n"
+ "Pay to the Order of: "
+ name
+ " $"
+ checkAmount
+ "\n"
+ checkWords
+ "\n"
+ "------------------------------------------------------\n");
}
private static String checkToWords(String checkAmount) {
/**
* Here I will use the string.split() method to separate out
* the integer and decimal portions of the checkAmount.
*/
String delimiter = "\\.\\$";
/* Remove any commas from checkAmount */
checkAmount.replace(",", "");
/* Split the checkAmount string into an array */
String[] splitAmount = checkAmount.split(delimiter);
/* Convert the integer portion of checkAmount to words */
NumberToWords intToWord = new NumberToWords();
long intPortion = Long.parseLong(splitAmount[0]); // ERROR! (84)
intToWord.convert(intPortion);
String intAmount = intToWord.getString() + " dollars";
/* Convert the decimal portion of checkAmount to words */
String decAmount = "";
long decPortion = Long.parseLong(splitAmount[1]);
if (decPortion != 0) {
NumberToWords decToWord = new NumberToWords();
decToWord.convert(Long.parseLong(splitAmount[1]));
decAmount = " and " + decToWord.getString() + " cents.";
}
return (intAmount + decAmount);
}
}
Note that I am using external class files to handle validation of the name, date, currency, and conversion from numbers to words. These class files all work as intended.
The error I am getting is:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at CheckWriter.checkToWords(CheckWriter.java:82)
at CheckWriter.main(CheckWriter.java:46)
I have commented the lines in my code that are causing the errors that I am experiencing.
Could someone please assist me in figuring where my code is going wrong? I can include the other class files if you feel that it would be needed.
EDIT: When I run the code, it asks for the name and date. Before asking for the check amount is when it throws the error.
EDIT 2: A huge thank you to cotton.m! Thanks to his advice, I have changed the while statements to look like this:
while(!validateDate.validate(date) && date == "")
This has now fixed my issue. It would appear that when validating data with a regex expression, an empty string will return true.
The String you are trying to parse in an empty length string.
My suggestion would be to
1) Check the value of checkAmount at the start of checkToWords - if it is blank there's your problem
2) Don't do that split. Just replace the $ like you did the , (I think this is your real problem)
Also you are going to have another issue in that 10000.00 is not a long. I see you are splitting out the . but is that really what you want?
It is NumberFormatException, the value in checkAmount (method parameter) is not a valid Number.
You need to set checkAmount=checkAmount.replace(",", "");
Otherwise checkAmount will still have , inside and causes NumberFormatExcpetion.
Your issue is with your delimiter regex, currently you are using \.\$ which will split on a literal . followed by a literal $. I'm assuming that what you are actually intending to do is to split on either a . or a $, so change your delimiter to one of the following:
String delimiter = "\\.|\\$"
or
String delimiter = "[\\.\\$]"
As your code is now, checkAmount.split(delimiter) is not actually successfully splitting the string anywhere, so Long.parseLong(splitAmount[0]) is equivalent to Long.parseLong(checkAmount).
It should be:
String delimiter = "[\\.\\$]";
and then you have to check that splitWord[i] is not empty.