Errors When Running Java from Command Prompt - java

I am having issues with running a java program from Command Prompt. I have a java file called DataRecover, and I have a second java file that is called Triple. Now, when I run javac Triple.java in Command Prompt, it does what it is supposed to. However, when I run javac DataRecover.java, it comes with this error message: "Exception in thread "main" java.lang.NoClassDefFoundError: DataRecover (wrong name: projectbeng\DataRecover
DataRecover.java:61: error: cannot find symbol
static Triple extractTriples(String str) {
^
symbol: class Triple
location: class DataRecover
DataRecover.java:30: error: cannot find symbol
Triple triples = extractTriples(line);
^
symbol: class Triple
location: class DataRecover
EDIT: I have included both classes. I have now been able to run the javac command, and there is a CLASS file for each in the proper folder. Now, I need to run the DataRecover file in Command Prompt. When I run "java DataRecover" I get the following error: "Exception in thread "main" java.lang.NoClassDefFoundError: DataRecover (wrong name: projectbeng\DataRecover)".
package projectbeng;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
import java.io.IOException;
public class DataRecover {
public static void main(String[] args) throws Exception {
//Create a Scanner for the user
Scanner sc = new Scanner(System.in);
System.out.print("Enter file name to process: ");
File fileName = new File(sc.nextLine() + ".txt"); //Do not include the .txt extension
if(!fileName.exists()){ //does not exist
throw new IOException("File \"" + fileName + "\" not found.");
}
System.out.println("\nProcessing file: " + fileName + "\n----------------------------------------");
BufferedReader br = new BufferedReader(new FileReader(fileName));
int lineCount = 0; //assumes file does not end with a new line character
int tripleLineCount = 0;
int tripleCount = 0;
String line = "";
//Read data from file
while((line = br.readLine()) != null){ //has another line in the file
lineCount++;
if(!line.equals("")) { //is not a blank line
Triple triples = extractTriples(line);
if(triples.getHasTriple()) { //line contains triples
System.out.println(triples.getTriples());
tripleLineCount++;
}
for(int j = 0; j < triples.getTriples().length(); j++) {
if(triples.getTriples().charAt(j) == '(') tripleCount++;
}
}
}
//prints out the summary of the file
System.out.println("\nSummary\n----------------------------------------");
System.out.println("Total lines: " + lineCount);
System.out.println("Lines containing triples: " + tripleLineCount);
System.out.println("Total number of triples: " + tripleCount);
}
/*Given a string, returns a Triple with a string containing the triples (if any) and a boolean stating whether
or not it contains a triple.
Assumptions:
1.) If a '-' sign is found, it has been added. If preceeding a number (for example -32), the number is 32 where
the '-' sign is simply garbage.
2.) If a '.' is found in a number (for example 2.32), the potential integers are 2 and 32 where the '.' is
garbage.
3.) For part c, if the first valid character found is a letter, this will always be the real triple. It does not
matter whether or not it is part of a word (for example, if it comes across "Dog a", 'D' will be the triple.)
4.) The strings "<null>", "<cr>", "<lf>", and "<eof>" as well as multi-digit numbers (ex. 32) count as single
characters. Thus, they cannot be broken up (no garbage in between the characters).
*/
static Triple extractTriples(String str) {
/*Grammar:
Triple is in form (a,b,c) where a is either a non-negative integer or the string "<null>", b is a
non-negative integer where b <= a (b must be 0 if a is <null>), and c is either an individual letter
(upper or lower case), period, colon, semicolon, or one of the three strings "<cr>", "<lf>", or "<eof>".
state == 0 ==> needs left parenthesis
state == 1 ==> needs right parenthesis
state == 2 ==> needs comma
state == 3 ==> needs a
state == 4 ==> needs b
state == 5 ==> needs c
*/
int state = 0;
int a = -1;
int b = -1;
String triples = "";
String tempTriples = "";
for(int i = 0; i < str.length(); i++) {
if(str.charAt(i) == '.' || str.charAt(i) == ':' || str.charAt(i) == ';' || str.charAt(i) == '<' ||
(str.charAt(i) >= 'a' && str.charAt(i) <= 'z') || (str.charAt(i) >= 'A' && str.charAt(i) <= 'Z')
|| (str.charAt(i) >= '0' && str.charAt(i) <= '9') || str.charAt(i) == ',' ||
str.charAt(i) == '(' || str.charAt(i) == ')') {
if(state == 0) {
if(str.charAt(i) == '(') {
tempTriples = str.substring(i, i+1);
state = 3;
}
}else if(state == 1) {
if(str.charAt(i) == ')') {
triples = triples + tempTriples + str.substring(i, i+1) + " ";
tempTriples = "";
state = 0;
a = -1;
b = -1;
}
}else if(state == 2) {
if(str.charAt(i) == ',') {
tempTriples = tempTriples + str.substring(i, i+1);
if(b != -1) state = 5;
else state = 4;
}
}else if(state == 3) {
if(str.charAt(i) >= '0' && str.charAt(i) <= '9') {
int j = i;
while(j < str.length() && str.charAt(j) >= '0' && str.charAt(j) <= '9') j++;
a = Integer.parseInt(str.substring(i, j));
i = j - 1;
tempTriples = tempTriples + a;
state = 2;
}else if(str.length() > i + 5 && str.substring(i, i+6).equals("<null>")) {
a = 0;
tempTriples = tempTriples + str.substring(i, str.indexOf(">", i)+1);
i = str.indexOf(">", i);
state = 2;
}
}else if(state == 4) {
if(str.charAt(i) >= '0' && str.charAt(i) <= '9') {
int j = i;
while(j < str.length() && str.charAt(j) >= '0' && str.charAt(j) <= '9') j++;
b = Integer.parseInt(str.substring(i, j));
i = j - 1;
if(b <= a) {
tempTriples = tempTriples + b;
state = 2;
}else b = -1;
}
}else if(state == 5) {
if(str.charAt(i) == '.' || str.charAt(i) == ':'||(str.charAt(i) <= 'z' && str.charAt(i) >= 'a')
|| str.charAt(i) == ';' || (str.charAt(i) <= 'Z' && str.charAt(i) >= 'A')) {
tempTriples = tempTriples + str.substring(i, i+1);
state = 1;
}else if((str.length() > i + 4 && str.substring(i, i+5).equals("<eof>")) ||
(str.length() > i + 3 && (str.substring(i, i+4).equals("<cr>") ||
str.substring(i, i+4).equals("<lf>")))) {
tempTriples = tempTriples + str.substring(i, str.indexOf(">", i)+1);
i = str.indexOf(">", i);
state = 1;
}else if(str.length() > i + 5 && str.substring(i, i+6).equals("<null>")) {
i = str.indexOf(">", i);
}
}
}
}
Triple triple = new Triple(true, triples);
if(triples.equals("")) triple.setHasTriple(false); //does not contain a triple
return triple;
}
package projectbeng;
class Triple {
boolean hasTriple = this.hasTriple;
String triple = this.triple;
//creates a new Triple
Triple(boolean newHasTriple, String newTriple){
this.hasTriple = newHasTriple;
this.triple = newTriple;
}
//returns whether or not Triple contains any triples
boolean getHasTriple() {
return hasTriple;
}
//returns the triples in Triple
String getTriples() {
return triple;
}
//changes the state of whether a Triple contains triples
void setHasTriple(boolean newHasTriple){
this.hasTriple = newHasTriple;
}
}
What is the proper way to run the DataRecover file through Command Prompt?

When you are referencing the source files in other files, you have to give all those files together. In your case it should be:
javac Triple.java DataRecover.java
Many modern Java projects use build tools to help with the management of source files. Two popular Java build tools are Gradle and Maven.

Related

String Index Exception

I was trying to convert an expression from infix form to postfix form.I used String a, p , s for stack, postfix result expression, input expression respectively.
Every time I am getting this error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: -1 at
java.lang.String.charAt(String.java:658) at
javaapplication4.A.conversion(A.java:50) at
javaapplication4.A.main(A.java:83)
Please help me how can I solve it.
Here is my code:
import java.util.Scanner;
public class A {
String a="(", s = "", p = "";
int i, n = 1, top = 0, pp = 0;
void push(char ch) {
a = a + ch;
top = n;
n++;
}
void pop() {
n--;
top--;
}
int prio(char ch) {
int f = -1;
if (ch == '(') {
f = 0;
} else if (ch == '+' || ch == '-') {
f = 1;
} else if (ch == '*' || ch == '/' || ch == '%') {
f = 2;
} else if (ch == '^') {
f = 3;
}
return f;
}
void conversion() {
System.out.print("Enter infix form: ");
Scanner sd = new Scanner(System.in);
s = sd.nextLine();
//System.out.println(s);
int t, j, sz;
sz = s.length();
for (i = 0; i < sz; i++) {
if (s.charAt(i) >= '0' && s.charAt(i) <= '9') {
p = p + s.charAt(i);
pp++;
} else if (s.charAt(i) == '(') {
push('(');
} else if (s.charAt(i) == '-' || s.charAt(i) == '+' || s.charAt(i) == '*' || s.charAt(i) == '/' || s.charAt(i) == '%' || s.charAt(i) == '^') {
j = prio(s.charAt(i));
t = prio(a.charAt(top));
//System.out.println(t+" "+j);
while (j <= t) {
p = p + a.charAt(top);
pp++;
pop();
t = prio(a.charAt(top));
}
push(s.charAt(i));
} else if (s.charAt(i) == ')') {
while (a.charAt(top) != '(') {
p = p + a.charAt(top);
pp++;
pop();
}
pop();
}
}
while (a.charAt(top) != '(') {
p = p + a.charAt(top);
pp++;
pop();
}
pop();
}
void postfix() {
System.out.print("postfix form is: ");
System.out.println(p);
}
public static void main(String args[]) {
A h = new A();
h.conversion();
h.postfix();
//System.out.println(h.a);
//System.out.println(h.s);
}
}
Can you confirm if the error is here?
while (a.charAt(top) != '(')
Inside the loop you continuously pop(), which decrements from top, which has the risk of going negative if a match is never found. Even if the error is not here, it should check for that condition.
You may have made an extra pop() definition. Can you check this?

program get error Exception in thread "main" java.lang.NumberFormatException: when iterate a math expression [duplicate]

This question already has answers here:
What is a NumberFormatException and how can I fix it?
(9 answers)
Closed 2 years ago.
When I try to use the function to iterate the user input expression, I get the java.lang.NumberFormatException, I try fixing the loop much time, but I still cannot understand where did it when wrong. The IDE suggest it went wrong in the parstInt while loop
Here is the code:
import java.util.Scanner;
import java.util.Stack;
static Stack<Integer> stackForOperand = new Stack<Integer>();
static Stack<Character> stackForOperator = new Stack<Character>();
public static int processOneOperator(char stackForOperator, int num1, int num2) {
int result = 0;
switch (stackForOperator) {
case '+':
result = num1 + num2;
case '-':
result = num1 - num2;
case '*':
result = num1 * num2;
case '/':
if (num2 != 0) {
result = num1 / num2;
} else {
throw new UnsupportedOperationException("divide by zero error");
}
}
return result;
}
public static boolean num_order(char first, char second) {
if (first == '(' || second == ')') {
return false;
} else if ((first == '*' || first == '/') && (second == '+' || second == '-')) {
return false;
} else {
return true;
}
}
public static int calculation_loop(String expression) {
for (int i = 0; i < expression.length(); i++) {
if (expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
String more_num = "";
while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
more_num += expression.charAt(i++);
int more_num2 = Integer.parseInt(more_num);
stackForOperand.push(more_num2);
i--;
}
} else if (expression.charAt(i) == '(') {
stackForOperator.push(expression.charAt(i));
} else if (expression.charAt(i) == ')') {
while (stackForOperator.peek() != '(') {
stackForOperand.push(
processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
stackForOperator.pop();
}
} else if (expression.charAt(i) == '+' || expression.charAt(i) == '-' || expression.charAt(i) == '*'
|| expression.charAt(i) == '/') {
while (!stackForOperator.empty() && num_order(expression.charAt(i), stackForOperator.peek())) {
stackForOperand.push(
processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
stackForOperator.push(expression.charAt(i));
}
}
}
while (!stackForOperator.empty()) {
stackForOperand
.push(processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
}
return stackForOperand.pop();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("/");
String input = scanner.nextLine();
input = input.replaceAll("\\s+", "");
System.out.println(input);
Integer output = calculation_loop(input);
System.out.println(output);
}
}
Looking at this piece of code:
public static int calculation_loop(String expression) {
for (int i = 0; i < expression.length(); i++) {
if (expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
String more_num = "";
while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
more_num += expression.charAt(i++);
int more_num2 = Integer.parseInt(more_num);
stackForOperand.push(more_num2);
i--;
}
So. Suppose having such an expression "2345+6789". According to your code i is incrementing and decrementing before end of while loop.
while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
more_num += expression.charAt(i++);
...
i--;
}
Is this your intention? It makes your loop infinite and it finishes only because number format exception is thrown while parsing. This is why I think your parser throws exception: You got the digit '2' in first place, concatenate it with more_num, then increment the i, after that decrement the i and at the next iteration you have the same previous position with same char '2', then concatenate it again to more_num ad infinitum. And first you parse more_num which is "2", on next iteration you append one more '2' and more_num "22" then "222"... Till it become bigger than type int can hold like "22222222222222222222222" and exception is thrown
Second thing. Suppose you remove i-- and your loop will normally iterate the next char. So, your stackForOperand will push first the number 2, then will push the number 23 then the number 234, then will push the number 2345. Is that your intension? I think more logically is to move Integer.parseInt and stackForOperand.push after the while loop
public static int calculation_loop(String expression) {
for (int i = 0; i < expression.length(); i++) {
if (expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
String more_num = "";
while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
more_num += expression.charAt(i++);
}
int more_num2 = Integer.parseInt(more_num);
stackForOperand.push(more_num2);

Print the number of unique vowels in a string, Java

I need to find the number of distinct vowels. I came up with the code below but it can't make distinction between same vowels:
public static int count_Vowels(String str) {
str = str.toLowerCase();
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == 'a' || str.charAt(i) == 'e' || str.charAt(i) == 'i'
|| str.charAt(i) == 'o' || str.charAt(i) == 'u') {
count++;
}
}
return count;
}
I would start with five variables (one for each vowel) set to 0, iterate the characters in the input and set the corresponding variable to 1 if I find a match, and simply return the accumulated value of said variables. Like,
public static int count_Vowels(String str) {
int a = 0, e = 0, i = 0, o = 0, u = 0;
for (char ch : str.toLowerCase().toCharArray()) {
if (ch == 'a') {
a = 1;
} else if (ch == 'e') {
e = 1;
} else if (ch == 'i') {
i = 1;
} else if (ch == 'o') {
o = 1;
} else if (ch == 'u') {
u = 1;
}
}
return a + e + i + o + u;
}
You could use Set data structure and instead of incrementing the counter just add vowels to the set. At the end you can return just the size of the set.
The problem in your code is that you are not counting the distinct vowels, but all the vowels in the string. A Java-8 way to this:
public static int countDistinctVowels(String str) {
str = str.toLowerCase();
int count = (int) str.chars() // get IntStream of chars
.mapToObj(c -> (char) c) // cast to char
.filter(c -> "aeiou".indexOf(c) > -1) // remove all non-vowels
.distinct() // keep the distinct values
.count(); // count the values
return count;
}
Also use proper Java naming conventions: countDistinctVowels, no count_Distinct_Vowels.
there's definitely an issue here with this counting. at the very least. you should rethink this:
if (str.charAt(i) == 'a' || str.charAt(i) == 'e' || str.charAt(i) == 'i'
|| str.charAt(i) == 'o' || str.charAt(i) == 'u')
count++;
You could use the method contains
public static int count_Vowels(String str) {
str = str.toLowerCase();
int count = 0;
count += string.contains("a") ? 1 : 0;
count += string.contains("e") ? 1 : 0;
count += string.contains("i") ? 1 : 0;
count += string.contains("o") ? 1 : 0;
count += string.contains("u") ? 1 : 0;
return count;
}
I made explanations in the comments to the code:
public static int count_Vowels(String str) {
str = str.toLowerCase();
Set<Character> setOfUsedChars = new HashSet<>(); // Here you store used vowels
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == 'a' || str.charAt(i) == 'e' || str.charAt(i) == 'i'
|| str.charAt(i) == 'o' || str.charAt(i) == 'u') { // if currently checked character is vowel...
setOfUsedChars.add(str.charAt(i)); // add this vowel to setOfUsedChars
}
}
return setOfUsedChars.size(); // size of this sets is a number of vowels present in input String
}
static void vow(String input){
String output=input.toLowerCase();
int flaga=0,flage=0,flagi=0,flago=0,flagu=0;
for(int i=0;i<input.length();i++) {
if((output.charAt(i))=='a' && flaga==0) {
System.out.print(input.charAt(i)+" ");
flaga++;
}
if(output.charAt(i)=='e' && flage==0) {
System.out.print(input.charAt(i)+" ");
flage++;
}
if(output.charAt(i)=='i' && flagi==0) {
System.out.print(input.charAt(i)+" ");
flagi++;
}
if(output.charAt(i)=='o' && flago==0) {
System.out.print(input.charAt(i)+" ");
flago++;
}
if(output.charAt(i)=='u' && flagu==0) {
System.out.print(input.charAt(i)+" ");
flagu++;
}
}
}
public static void main(String args[]) {
String sentence;
int v=0,c=0,ws=0;
Scanner sc= new Scanner(System.in);
sentence = sc.nextLine();
sc.close();
sentence.toLowerCase();
String res="";
for(int i=0;i<sentence.length();i++) {
if(sentence.charAt(i)=='a'||sentence.charAt(i)=='e'||sentence.charAt(i)=='i'||sentence.charAt(i)=='o'||sentence.charAt(i)=='u') {
if(res.indexOf(sentence.charAt(i))<0) {
res+=sentence.charAt(i);
v++;
}//System.out.println(res.indexOf(sentence.charAt(i)));
}
else if(sentence.charAt(i)==' ')
ws++;
else c++;
}
System.out.println(res);
System.out.println("no of vowels: "+v+"\n"+"no of consonants: "+c+"\n"+"no of
white spaces: "+ws);
}
You can use this Method to Find Count of Distinct vowels.
public static int count_Vowels(String str) {
char[] c = str.toLowerCase().toCharArray();
int Counter=0;
String NewString="";
for(int i=0;i<c.length;i++){
String tempString="";
tempString+=c[i];
if(!NewString.contains(tempString) && (c[i]=='a'||c[i]=='e'||c[i]=='i'||c[i]=='o'||c[i]=='u')){
Counter++;
NewString+=c[i];
}
}
return Counter;
}
Here is a solve for this problem without using objects. It's a crude but great solve for beginners who encounter this problem with limited js experience.
How to count unique vowels is a string;
function hasUniqueFourVowels(str){
let va = 0
let ve = 0
let vi = 0
let vo = 0
let vu = 0
let sum = 0
for(let i = 0; i < str.length; i++){
let char = str[i];
if(char === "i"){
vi = 1
}
if(char === "e"){
ve = 1
}
if(char === "a"){
va = 1
}
if(char === "o"){
vo = 1
}
if(char === "u"){
vu = 1
}
sum = va + vi + vo + ve + vu
if (sum >= 4){
return true
}
}
return false
}
#Test
public void numfindVoweles(){
String s="aeiouaedtesssiou";
char a[]=s.toCharArray();
HashMap<Character,Integer> hp= new HashMap<Character, Integer>();
for(char ch:a){
if(hp.containsKey(ch) && (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u')){
hp.put(ch,hp.get(ch)+1);
}
else if(ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u'){
hp.put(ch,1);
}
}
System.out.println(hp);
}

Using replace to take a character and change it to another in java

I am trying to figure out how to remove certain characters to make it English after it being in l33t speak. For example, I 54w 3 5hip5, would translate to I saw 3 ships. I need the 3 to stay a 3 here but in, N3v3r f0rg37 y0|_|r t0w31, I would need the 3's to become e's. Here is my code as follows. All the characters translate over correctly, but I just can't figure out how to do the 3's to e's.
My question is, what is needed to be added to get the 3's to be e's at a certain time, and to have my 3's stay 3's another time. Just so that you know, is that we aren't allowed to use regex, arrays, or string builder for this.
Rules are that if the number is supposed to be a number that it stays a number when you translate it from l33t to English, if the l33t number is a letter than you replace the number and turn it into the letter that corresponds to it.
I also have a different block of code that already takes into consideration the 3 to e's, but instead adds two u's instead of one.
Here are the replacements for the letters, a = 4, b = 8, e = 3, l = 1, o = 0, s = 5, t = 7, u = |_|, z = 2.
I decided to go the route of mike's answer since I understand exactly what's going on.
Thanks to everyone for the help!
Input/Output examples
This following code translates
I 54w 3 5hip5
to
I saw 3 ships
and
3 5hip5 4r3 c0ming m3 w4y
to
3 ships are coming me way
Code
public static String translateToEnglish(String phrase) {
if (phrase == null)
return null;
boolean threeAtBeginning = false, threeAtEnd = fal;
if (phrase.charAt(0) == '3' && phrase.charAt(1) == ' ')
threeAtBeginning = true;
int length = phrase.length();
if (phrase.charAt(length - 1) == '3' && phrase.charAt(length - 2) == ' ')
threeAtEnd = true;
String finished = phrase.replace('4', 'a') .replace('1', 'l') .replace('2', 'z') .replace('5', 's') .replace('8', 'b') .replace('0', 'o') .replace('7', 't') .replace("|_|", "u") .replace("3", "e");
finished = finished.replace(" e ", " 3 ");
if (threeAtBeginning)
finished = '3' + finished.substring(1);
if (threeAtEnd)
finished = finished.substring(0, length - 1) + '3';
return finished;
}
This is clearly homework, and the restrictions are clearly intended to prevent any sane solution, but here's an O(n^2) solution that seems to avoid the restrictions:
public class RemoveL33t {
public static void main(String[] args) {
System.out.println(removeL33t("I 54w 3 5hip5"));
System.out.println(removeL33t("I 54w 33 5hip5"));
System.out.println(removeL33t("I 54w 45 5hip5"));
System.out.println(removeL33t("N3v3r f0rg37 y0|_|r t0w31"));
}
public static String removeL33t(String s) {
String result = "";
for (int pos = 0;;) {
// Find the beginning of the next word.
int whitespaceBegin = pos;
while (pos < s.length() && Character.isWhitespace(s.charAt(pos))) {
pos++;
}
// Add the whitespace to the result.
result += s.substring(whitespaceBegin, pos);
// If there is no next word, then we're done.
if (pos >= s.length()) {
return result;
}
// Find the end of the word. Determine if the word is entirely numbers.
int wordBegin = pos;
boolean nonNumber = false;
while (pos < s.length() && !Character.isWhitespace(s.charAt(pos))) {
nonNumber |= s.charAt(pos) < '0' || s.charAt(pos) > '9';
pos++;
}
// Append the word. Perform replacements if it contains a non-number.
if (nonNumber) {
result += s.substring(wordBegin, pos)
.replace('4', 'a')
.replace('8', 'b')
.replace('3', 'e')
.replace('1', 'l')
.replace('0', 'o')
.replace('5', 's')
.replace('7', 't')
.replace("|_|", "u")
.replace('2', 'z');
} else {
result += s.substring(wordBegin, pos);
}
}
}
}
I think this is it.
public static String translateToEnglish(String phrase) {
if (phrase == null) {
return null;
}
String finished = phrase.replace('4', 'a') .replace('1', 'l') .replace('2', 'z') .replace('5', 's') .replace('8', 'b') .replace('0', 'o') .replace('7', 't') .replace("|_|", "u") .replace("3", "e");
finished = finished.replace(" e ", " 3 ");
if(finished.startsWith("e ")){
finished = "3 " + finished.substring(2);
}
if(finished.endsWith(" e")){
finished = finished.substring(0, finished.length()-2) + " 3";
}
return finished;
}
I don't know if this is the answer, but is the best i could think of
public static void main (String[] args) throws java.lang.Exception
{
String c = "I 54w 45 5hip5";
for(String s: c.split(" ")){
try{
Integer.parseInt(s);
System.out.print(s + " ");
}
catch(NumberFormatException e){
s = s.replace('4', 'a').replace('1', 'l').replace('2', 'z').replace('5', 's').replace('8', 'b').replace('0', 'o').replace('7', 't').replace("|_|", "u").replace("3", "e");
System.out.print(s + " ");
}
}
}
This is for your "new" code that you decided to use, or this could just be an alternate solution. The input/output is identical to the samples I gave in my other answer:
public static String translateToEnglish(String phrase) {
if (phrase == null)
return null;
String finished = "";
for (int i = 0; i < phrase.length(); i++) {
char c = phrase.charAt(i);
if (c == '4')
finished += 'a';
else if (c == '3') {
if (i != phrase.length() - 1)
{
if (phrase.charAt(i + 1) == ' ') {
if (i == 0)
finished += c;
else
if (phrase.charAt(i - 1) == ' ')
finished += c;
else
finished += 'e';
}
else
finished += 'e';
}
else
{
if (phrase.charAt(i - 1) == ' ')
finished += c;
else
finished += 'e';
}
} else if (c == '1')
finished += 'l';
else if (c == '2')
finished += 'z';
else if (c == '5')
finished += 's';
else if (c == '7')
finished +='t';
else if (c == '8')
finished += 'b';
else if (c == '0')
finished += 'o';
else if (i + 2 < phrase.length() && phrase.charAt(i + 1) == '_' && phrase.charAt(i + 2) == '|') {
finished += 'u';
i += 2;
} else
finished += c;
}
return finished;
}

removing invalid XML characters from a string in java

Hi
i would like to remove all invalid XML characters from a string.
i would like to use a regular expression with the string.replace method.
like
line.replace(regExp,"");
what is the right regExp to use ?
invalid XML character is everything that is not this :
[#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
thanks.
Java's regex supports supplementary characters, so you can specify those high ranges with two UTF-16 encoded chars.
Here is the pattern for removing characters that are illegal in XML 1.0:
// XML 1.0
// #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
String xml10pattern = "[^"
+ "\u0009\r\n"
+ "\u0020-\uD7FF"
+ "\uE000-\uFFFD"
+ "\ud800\udc00-\udbff\udfff"
+ "]";
Most people will want the XML 1.0 version.
Here is the pattern for removing characters that are illegal in XML 1.1:
// XML 1.1
// [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
String xml11pattern = "[^"
+ "\u0001-\uD7FF"
+ "\uE000-\uFFFD"
+ "\ud800\udc00-\udbff\udfff"
+ "]+";
You will need to use String.replaceAll(...) and not String.replace(...).
String illegal = "Hello, World!\0";
String legal = illegal.replaceAll(pattern, "");
Should we consider surrogate characters? otherwise '(current >= 0x10000) && (current <= 0x10FFFF)' will never be true.
Also tested that the regex way seems slower than the following loop.
if (null == text || text.isEmpty()) {
return text;
}
final int len = text.length();
char current = 0;
int codePoint = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
current = text.charAt(i);
boolean surrogate = false;
if (Character.isHighSurrogate(current)
&& i + 1 < len && Character.isLowSurrogate(text.charAt(i + 1))) {
surrogate = true;
codePoint = text.codePointAt(i++);
} else {
codePoint = current;
}
if ((codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD)
|| ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
|| ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
|| ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF))) {
sb.append(current);
if (surrogate) {
sb.append(text.charAt(i));
}
}
}
All these answers so far only replace the characters themselves. But sometimes an XML document will have invalid XML entity sequences resulting in errors. For example, if you have  in your xml, a java xml parser will throw Illegal character entity: expansion character (code 0x2 at ....
Here is a simple java program that can replace those invalid entity sequences.
public final Pattern XML_ENTITY_PATTERN = Pattern.compile("\\&\\#(?:x([0-9a-fA-F]+)|([0-9]+))\\;");
/**
* Remove problematic xml entities from the xml string so that you can parse it with java DOM / SAX libraries.
*/
String getCleanedXml(String xmlString) {
Matcher m = XML_ENTITY_PATTERN.matcher(xmlString);
Set<String> replaceSet = new HashSet<>();
while (m.find()) {
String group = m.group(1);
int val;
if (group != null) {
val = Integer.parseInt(group, 16);
if (isInvalidXmlChar(val)) {
replaceSet.add("&#x" + group + ";");
}
} else if ((group = m.group(2)) != null) {
val = Integer.parseInt(group);
if (isInvalidXmlChar(val)) {
replaceSet.add("&#" + group + ";");
}
}
}
String cleanedXmlString = xmlString;
for (String replacer : replaceSet) {
cleanedXmlString = cleanedXmlString.replaceAll(replacer, "");
}
return cleanedXmlString;
}
private boolean isInvalidXmlChar(int val) {
if (val == 0x9 || val == 0xA || val == 0xD ||
val >= 0x20 && val <= 0xD7FF ||
val >= 0x10000 && val <= 0x10FFFF) {
return false;
}
return true;
}
Jun's solution, simplified. Using StringBuffer#appendCodePoint(int), I need no char current or String#charAt(int). I can tell a surrogate pair by checking if codePoint is greater than 0xFFFF.
(It is not necessary to do the i++, since a low surrogate wouldn't pass the filter. But then one would re-use the code for different code points and it would fail. I prefer programming to hacking.)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
int codePoint = text.codePointAt(i);
if (codePoint > 0xFFFF) {
i++;
}
if ((codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD)
|| ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
|| ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
|| ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF))) {
sb.appendCodePoint(codePoint);
}
}
String xmlData = xmlData.codePoints().filter(c -> isValidXMLChar(c)).collect(StringBuilder::new,
StringBuilder::appendCodePoint, StringBuilder::append).toString();
private boolean isValidXMLChar(int c) {
if((c == 0x9) ||
(c == 0xA) ||
(c == 0xD) ||
((c >= 0x20) && (c <= 0xD7FF)) ||
((c >= 0xE000) && (c <= 0xFFFD)) ||
((c >= 0x10000) && (c <= 0x10FFFF)))
{
return true;
}
return false;
}
From Mark McLaren's Weblog
/**
* This method ensures that the output String has only
* valid XML unicode characters as specified by the
* XML 1.0 standard. For reference, please see
* <a href="http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char">the
* standard</a>. This method will return an empty
* String if the input is null or empty.
*
* #param in The String whose non-valid characters we want to remove.
* #return The in String, stripped of non-valid characters.
*/
public static String stripNonValidXMLCharacters(String in) {
StringBuffer out = new StringBuffer(); // Used to hold the output.
char current; // Used to reference the current character.
if (in == null || ("".equals(in))) return ""; // vacancy test.
for (int i = 0; i < in.length(); i++) {
current = in.charAt(i); // NOTE: No IndexOutOfBoundsException caught here; it should not happen.
if ((current == 0x9) ||
(current == 0xA) ||
(current == 0xD) ||
((current >= 0x20) && (current <= 0xD7FF)) ||
((current >= 0xE000) && (current <= 0xFFFD)) ||
((current >= 0x10000) && (current <= 0x10FFFF)))
out.append(current);
}
return out.toString();
}
From Best way to encode text data for XML in Java?
String xmlEscapeText(String t) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < t.length(); i++){
char c = t.charAt(i);
switch(c){
case '<': sb.append("<"); break;
case '>': sb.append(">"); break;
case '\"': sb.append("""); break;
case '&': sb.append("&"); break;
case '\'': sb.append("&apos;"); break;
default:
if(c>0x7e) {
sb.append("&#"+((int)c)+";");
}else
sb.append(c);
}
}
return sb.toString();
}
If you want to store text elements with the forbidden characters in XML-like form, you can use XPL instead. The dev-kit provides concurrent XPL to XML and XML processing - which means no time cost to the translation from XPL to XML. Or, if you don't need the full power of XML (namespaces), you can just use XPL.
Web Page: HLL XPL
I believe that the following articles may help you.
http://commons.apache.org/lang/api-2.1/org/apache/commons/lang/StringEscapeUtils.html
http://www.javapractices.com/topic/TopicAction.do?Id=96
Shortly, try to use StringEscapeUtils from Jakarta project.

Categories