I am trying to remove the non-number characters from my string.
I have tried using the .replace() method but this returns with the error:
The method replace(char, char) in the type String is not applicable for the arguments (String, String)
Code:
Properties p = new Properties();
File f = new File("coords.txt");
if (f.exists()) {
FileInputStream in;
try {
in = new FileInputStream(f);
p.load(in);
in.close();
} catch (Exception e) {
System.err.println("Failed to load coordinates");
System.err.println(e.getMessage());
Button.waitForAnyPress();
System.exit(0);
}
} else {
System.out.println("No coordinates found");
while (!Button.ESCAPE.isPressed()) {
Thread.yield();
}
System.exit(0);
}
When I print out the string gg, initialized like:
String gg = p.toString();
I get the output: Object020f458.
My computer highlights the error on the replace:
gg = gg.replace("{", "");
gg = gg.replace("=", "");
gg = gg.replace("}", "");
int commaLoc = gg.indexOf(",");
int x = Integer.parseInt(gg.substring(0,commaLoc));
int y = Integer.parseInt(gg.substring(commaLoc + 1));
So I was having a look at NXT and its APIs (JavaDocs)
Btw, I am by no mean an expert on NXT and leJOS, I'm guessing.
You can see by the JavaDoc, that the replace(CharSequence, CharSequence) method is not present.
While I wouldn't solve the problem in such a way, you can try using a StringBuilder to remove the unwanted chars.
See for example a Jon Skeet answer for ideas
https://stackoverflow.com/a/3472705/1392277
You can extract a method such as:
private String removeChars(
final String originalString,
final String charsToRemove) {
final StringBuilder stringBuilder = new StringBuilder(originalString);
int i = stringBuilder.indexOf(charsToRemove);
while (i != -1) {
stringBuilder.replace(i, i + charsToRemove.length(), "");
i = stringBuilder.indexOf(charsToRemove, i);
}
return stringBuilder.toString();
}
problem:
gg = gg.replace("{", "");
gg = gg.replace("=", "");
gg = gg.replace("}", "");
error message:
The method replace(char, char) in the type String is not applicable for the arguments (String, String)
Please try to replace with Character.MIN_VALUE:
Replace " with ', then replace all '' (, since java "doesn't like the empty character literal") with Character.MIN_VALUE):
gg = gg.replace('{', Character.MIN_VALUE);
gg = gg.replace('=', Character.MIN_VALUE);
gg = gg.replace('}', Character.MIN_VALUE);
Character.MIN_VALUE is not empty character, but closest to it :), and converts (with a String.replcae(char,char) test):
{foo=bar}
to:
\u0000foo\u0000bar\u0000
...which appears hard to copy&paste, but "looks like blanks" :)
Since the String I was using was actually using was a property I had to retrieve it like a property which will format it itself
int Count = Integer.parseInt(p.getProperty("Number_of_properties"));
for(int i = 1; i < Count; i++)
{
int x = Integer.parseInt(p.getProperty("x"+i));
int y = Integer.parseInt(p.getProperty("y"+i));
}
I also had to change my text file to match the property format:
Number_of_properties = 4
x1 = 150
y1 = 70
x2 = 55
y2 = 77
You can use
public String replaceAll(String regex, String replacement)
This will replace all matching expressions with the replacements.
gg = gg.replaceAll("{", ""); // replace all "{" with "".
gg = gg.replaceAll("=", "");
gg = gg.replaceAll("}", "");
The error must have been highlighted on below two line and not for replace function
int x = Integer.parseInt(gg.substring(0,commaLoc));
int y = Integer.parseInt(gg.substring(commaLoc + 1));
you forgot to put comma in second line. It should be
int y = Integer.parseInt(gg.substring(commaLoc, + 1));
Still it wont work because you are trying substring function with invalid range (as value of commaLoc is -1).
Try replacing those last two lines as below just to make it error free.
int x = Integer.parseInt(gg.substring(6, 7));
int y = Integer.parseInt(gg.substring(7, 8));
Related
I always get error that the arraylist in the sql statement is a varchar and not an int. And I tried to parse the arraylist in an integer variable but it keeps giving me the same error.
Code:
try {
String s = getIDUsuario().toString();
String s1 = s.split(" ")[1];
int id = Integer.parseInt(s1.charAt(2) + "");
Statement st = dataBase.conexionBD().createStatement();
ResultSet rs = st.executeQuery(" select * from Serveis where id_servei = " + id + "");
while (rs.next()) {
bytes = rs.getBytes("imatge_servei");
image = new BitmapDrawable(getResources(), BitmapFactory.decodeByteArray(bytes, 0, bytes.length));
try {
listaObjeto.add(new InfoServicio(getNombre(), rs.getString("titol"), rs.getString("descripcio"), getImagenPerfil(), image));
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
}
I don't fully understand what you mean by varchar '[3,4]',
But if you get this as a String, this is a gist of what you might want to do.
This String does not resemble an int entirely, so you won't be able to parse it as such.
String e = "varchar '[3,4]'";
String e2 = e.split(" ")[1]; // Split the string at SPACE and kept the last part.
// We can see that the numbers are at index 2 & 4 of the String e2.
// Therefore
int n1 = Integer.parseInt(e2.charAt(2) + ""); // Concatenated empty String with the char because the method takes a String.
int n2 = Integer.parseInt(e2.charAt(4) + ""); // Concatenated empty String with the char because the method takes a String.
I would like to count countX and countX using the same loop instead of creating three different loops. Is there any easy way approaching that?
public class Absence {
private static File file = new File("/Users/naplo.txt");
private static File file_out = new File("/Users/naplo_out.txt");
private static BufferedReader br = null;
private static BufferedWriter bw = null;
public static void main(String[] args) throws IOException {
int countSign = 0;
int countX = 0;
int countI = 0;
String sign = "#";
String absenceX = "X";
String absenceI = "I";
try {
br = new BufferedReader(new FileReader(file));
bw = new BufferedWriter(new FileWriter(file_out));
String st;
while ((st = br.readLine()) != null) {
for (String element : st.split(" ")) {
if (element.matches(sign)) {
countSign++;
continue;
}
if (element.matches(absenceX)) {
countX++;
continue;
}
if (element.matches(absenceI)) {
countI++;
}
}
}
System.out.println("2. exerc.: There are " + countSign + " rows int the file with that sign.");
System.out.println("3. exerc.: There are " + countX + " with sick note, and " + countI + " without sick note!");
} catch (FileNotFoundException ex) {
Logger.getLogger(Absence.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
text file example:
# 03 26
Jujuba Ibolya IXXXXXX
Maracuja Kolos XXXXXXX
I think you meant using less than 3 if statements. You can actually so it with no ifs.
In your for loop write this:
Countsign += (element.matches(sign)) ? 1 : 0;
CountX += (element.matches(absenceX)) ? 1 : 0;
CountI += (element.matches(absenceI)) ? 1 : 0;
Both answers check if the word (element) matches all regular expressions while this can (and should, if you ask me) be avoided since a word can match only one regex. I am referring to the continue part your original code has, which is good since you do not have to do any further checks.
So, I am leaving here one way to do it with Java 8 Streams in "one liner".
But let's assume the following regular expressions:
String absenceX = "X*";
String absenceI = "I.*";
and one more (for the sake of the example):
String onlyNumbers = "[0-9]*";
In order to have some matches on them.
The text is as you gave it.
public class Test {
public static void main(String[] args) throws IOException {
File desktop = new File(System.getProperty("user.home"), "Desktop");
File txtFile = new File(desktop, "test.txt");
String sign = "#";
String absenceX = "X*";
String absenceI = "I.*";
String onlyNumbers = "[0-9]*";
List<String> regexes = Arrays.asList(sign, absenceX, absenceI, onlyNumbers);
List<String> lines = Files.readAllLines(txtFile.toPath());
//#formatter:off
Map<String, Long> result = lines.stream()
.flatMap(line-> Stream.of(line.split(" "))) //map these lines to words
.map(word -> regexes.stream().filter(word::matches).findFirst()) //find the first regex this word matches
.filter(Optional::isPresent) //If it matches no regex, it will be ignored
.collect(Collectors.groupingBy(Optional::get, Collectors.counting())); //collect
System.out.println(result);
}
}
The result:
{X*=1, #=1, I.=2, [0-9]=2}
X*=1 came from word: XXXXXXX
#=1 came from word: #
I.*=2 came from words: IXXXXXX and Ibolya
[0-9]*=2 came from words: 03 and 06
Ignore the fact I load all lines in memory.
So I made it with the following lines to work. It escaped my attention that every character need to be separated from each other. Your ternary operation suggestion also nice so I will use it.
String myString;
while ((myString = br.readLine()) != null) {
String newString = myString.replaceAll("", " ").trim();
for (String element : newString.split(" ")) {
countSign += (element.matches(sign)) ? 1 : 0;
countX += (element.matches(absenceX)) ? 1 : 0;
countI += (element.matches(absenceI)) ? 1 : 0;
I am trying to write 2 different arrays to a csv. The first one I want in the first column, and second array in the second column, like so:
array1val1 array2val1
array1val2 array2val2
I am using the following code:
String userHomeFolder2 = System.getProperty("user.home") + "/Desktop";
String csvFile = (userHomeFolder2 + "/" + fileName.getText() + ".csv");
FileWriter writer = new FileWriter(csvFile);
final String NEW_LINE_SEPARATOR = "\n";
FileWriter fileWriter;
CSVPrinter csvFilePrinter;
CSVFormat csvFileFormat = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR);
fileWriter = new FileWriter(fileName.getText());
csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);
try (PrintWriter pw = new PrintWriter(csvFile)) {
pw.printf("%s\n", FILE_HEADER);
for(int z = 0; z < compSource.size(); z+=1) {
//below forces the result to get stored in below variable as a String type
String newStr=compSource.get(z);
String newStr2 = compSource2.get(z);
newStr.replaceAll(" ", "");
newStr2.replaceAll(" ", "");
String[] explode = newStr.split(",");
String[] explode2 = newStr2.split(",");
pw.printf("%s\n", explode, explode2);
}
}
catch (Exception e) {
System.out.println("Error in csvFileWriter");
e.printStackTrace();
} finally {
try {
fileWriter.flush();
fileWriter.close();
csvFilePrinter.close();
} catch (IOException e ) {
System.out.println("Error while flushing/closing");
}
}
However I am getting a strange output into the csv file:
[Ljava.lang.String;#17183ab4
I can run
pw.printf("%s\n", explode);
pw.printf("%s\n", explode2);
Instead of : pw.printf("%s\n", explode, explode2);
and it prints the actual strings but all in one same column.
Does anyone know how to solve this?
1.Your explode and explode2 are actually String Arrays. You are printing the arrays and not the values of it. So you get at the end the ADRESS of the array printed.
You should go through the arrays with a loop and print them out.
for(int i = 0; i<explode.length;++i) {
pw.printf("%s%s\n", explode[i], explode2[i]);
}
2.Also the method printf should be look something like
pw.printf("%s%s\n", explode, explode2);
because youre are printing two arguments, but in ("%s\n", explode, explode2) is only one printed.
Try it out and say if it worked
After these lines:
newStr.replaceAll(" ", "");
newStr2.replaceAll(" ", "");
String[] explode = newStr.split(",");
String[] explode2 = newStr2.split(",");
Use this code:
int maxLength = Math.max(explode.length, explode2.length);
for (int i = 0; i < maxLength; i++) {
String token1 = (i < explode.length) ? explode[i] : "";
String token2 = (i < explode2.length) ? explode2[i] : "";
pw.printf("%s %s\n", token1, token2);
}
This also cover the case that the arrays are of different length.
I have removed all unused variables and made some assumptions about content of compSource.
Moreover, don't forget String is immutable. If you just do "newStr.replaceAll(" ", "");", the replacement will be lost.
public class Tester {
#Test
public void test() throws IOException {
// I assumed compSource and compSource2 are like bellow
List<String> compSource = Arrays.asList("array1val1,array1val2");
List<String> compSource2 = Arrays.asList("array2val1,array2val2");
String userHomeFolder2 = System.getProperty("user.home") + "/Desktop";
String csvFile = (userHomeFolder2 + "/test.csv");
try (PrintWriter pw = new PrintWriter(csvFile)) {
pw.printf("%s\n", "val1,val2");
for (int z = 0; z < compSource.size(); z++) {
String newStr = compSource.get(z);
String newStr2 = compSource2.get(z);
// String is immutable --> store the result otherwise it will be lost
newStr = newStr.replaceAll(" ", "");
newStr2 = newStr2.replaceAll(" ", "");
String[] explode = newStr.split(",");
String[] explode2 = newStr2.split(",");
for (int k = 0; k < explode.length; k++) {
pw.println(explode[k] + "\t" + explode2[k]);
}
}
}
}
}
I am trying to read a PDF file in Java by using Itext. In my PDF file I have some calculation results. In a line there is an element and its two calculation results and they are not in a table. My PDF file looks like this :
I. Result X 12.551.734,75 9.284.925,26
. A. Result Y 8.583.482,18 416.187,03
. 1. result z 83.708,72 91.220,23
. 3. result a 8.499.773,46 324.966,80
. B. Result B 0,00 199.942,00
. 4. result c 0,00 199.942,00
. C. Result D 780.316,81 5.376.366,65
. 1. result e 66.041,73 3.962.399,52
. 2. result f 685.579,00 1.367.086,66
What I am trying to do is parse the string and its values. I couldn't find a proper way and I tried the code below. But the problem with this logic for the line :
. 1. result z 8.583.482,18 416.187,03
it prints just "." for the string then 1 and the first number. I couldn't get the whole ". 1. result z" part as string and then its values because it prints directly after seeing an int value and skips rest.
int page = 1;
PdfReader reader = new PdfReader(pdf);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
strategy = parser.processContent(page, new LocationTextExtractionStrategy());
Scanner scanner = new Scanner(strategy.getResultantText());
...
for (int j = page; j <= reader.getNumberOfPages(); j++) {
while (scanner.hasNextLine()) {
String nextToken = scanner.nextLine();
String rName = "";
StringTokenizer tok = new StringTokenizer(nextToken);
while (tok.hasMoreTokens()) {
String nToken = tok.nextToken();
try {
number = fmt.parse(nToken);
System.out.println(rName);
System.out.println(number);
while (tok.hasMoreTokens()) {
try {
nToken = tok.nextToken();
number = fmt.parse(nToken);
System.out.println(number);
} catch (ParseException e) {
if(rName.isEmpty()){
rName = nToken;
}else{
rName = rName + " " + nToken;
}
}
}
break;
} catch (ParseException e) {
if(rName.isEmpty()){
rName = nToken;
}else{
rName = rName + " " + nToken;
}
}
}
}
strategy = parser.processContent(++page, new LocationTextExtractionStrategy());
scanner = new Scanner(strategy.getResultantText());
}
How can I get these strings and their values correctly, could you help me please? Is there any other useful way to do it as I think this solution is not good enough?
Thank you for all the detail you provided. Typically you'd use a regular expression to parse complicated lines. Though sometimes programmatic parsing is a bit easier to follow. Rather than using the StringTokenizer to split the line, perhaps try:
String line = scanner.nextLine();
String[] tokens = line.split("\\s+");
String value1 = tokens[tokens.length-2];
String value2 = tokens[tokens.length-1];
String rowTitle = line.substring(0, line.indexOf(value1)).trim();
System.out.print(rowTitle + "\t");
System.out.print(value1 + "\t");
System.out.println(value2);
Text File(First three lines are simple to read, next three lines starts with p)
ThreadSize:2
ExistingRange:1-1000
NewRange:5000-10000
p:55 - AutoRefreshStoreCategories Data:Previous UserLogged:true Attribute:1 Attribute:16 Attribute:2060
p:25 - CrossPromoEditItemRule Data:New UserLogged:false Attribute:1 Attribute:10107 Attribute:10108
p:20 - CrossPromoManageRules Data:Previous UserLogged:true Attribute:1 Attribute:10107 Attribute:10108
Below is the code I wrote to parse the above file and after parsing it I am setting the corresponding values using its Setter. I just wanted to know whether I can improve this code more in terms of parsing and other things also by using other way like using RegEx? My main goal is to parse it and set the corresponding values. Any feedback or suggestions will be highly appreciated.
private List<Command> commands;
private static int noOfThreads = 3;
private static int startRange = 1;
private static int endRange = 1000;
private static int newStartRange = 5000;
private static int newEndRange = 10000;
private BufferedReader br = null;
private String sCurrentLine = null;
private int distributeRange = 100;
private List<String> values = new ArrayList<String>();
private String commandName;
private static String data;
private static boolean userLogged;
private static List<Integer> attributeID = new ArrayList<Integer>();
try {
// Initialize the system
commands = new LinkedList<Command>();
br = new BufferedReader(new FileReader("S:\\Testing\\Test1.txt"));
while ((sCurrentLine = br.readLine()) != null) {
if(sCurrentLine.contains("ThreadSize")) {
noOfThreads = Integer.parseInt(sCurrentLine.split(":")[1]);
} else if(sCurrentLine.contains("ExistingRange")) {
startRange = Integer.parseInt(sCurrentLine.split(":")[1].split("-")[0]);
endRange = Integer.parseInt(sCurrentLine.split(":")[1].split("-")[1]);
} else if(sCurrentLine.contains("NewRange")) {
newStartRange = Integer.parseInt(sCurrentLine.split(":")[1].split("-")[0]);
newEndRange = Integer.parseInt(sCurrentLine.split(":")[1].split("-")[1]);
} else {
allLines.add(Arrays.asList(sCurrentLine.split("\\s+")));
String key = sCurrentLine.split("-")[0].split(":")[1].trim();
String value = sCurrentLine.split("-")[1].trim();
values = Arrays.asList(sCurrentLine.split("-")[1].trim().split("\\s+"));
for(String s : values) {
if(s.contains("Data:")) {
data = s.split(":")[1];
} else if(s.contains("UserLogged:")) {
userLogged = Boolean.parseBoolean(s.split(":")[1]);
} else if(s.contains("Attribute:")) {
attributeID.add(Integer.parseInt(s.split(":")[1]));
} else {
commandName = s;
}
}
Command command = new Command();
command.setName(commandName);
command.setExecutionPercentage(Double.parseDouble(key));
command.setAttributeID(attributeID);
command.setDataCriteria(data);
command.setUserLogging(userLogged);
commands.add(command);
}
}
} catch(Exception e) {
System.out.println(e);
}
I think you should know what exactly you're expecting while using RegEx. http://java.sun.com/developer/technicalArticles/releases/1.4regex/ should be helpful.
To answer a comment:
p:55 - AutoRefreshStoreCategories Data:Previous UserLogged:true Attribute:1 Attribute:16 Attribute:2060
to parse above with regex (and 3 times Attribute:):
String parseLine = "p:55 - AutoRefreshStoreCategories Data:Previous UserLogged:true Attribute:1 Attribute:16 Attribute:2060";
Matcher m = Pattern
.compile(
"p:(\\d+)\\s-\\s(.*?)\\s+Data:(.*?)\\s+UserLogged:(.*?)\\s+Attribute:(\\d+)\\s+Attribute:(\\d+)\\s+Attribute:(\\d+)")
.matcher(parseLine);
if(m.find()) {
int p = Integer.parseInt(m.group(1));
String method = m.group(2);
String data = m.group(3);
boolean userLogged = Boolean.valueOf(m.group(4));
int at1 = Integer.parseInt(m.group(5));
int at2 = Integer.parseInt(m.group(6));
int at3 = Integer.parseInt(m.group(7));
System.out.println(p + " " + method + " " + data + " " + userLogged + " " + at1 + " " + at2 + " "
+ at3);
}
EDIT looking at your comment you still can use regex:
String parseLine = "p:55 - AutoRefreshStoreCategories Data:Previous UserLogged:true "
+ "Attribute:1 Attribute:16 Attribute:2060";
Matcher m = Pattern.compile("p:(\\d+)\\s-\\s(.*?)\\s+Data:(.*?)\\s+UserLogged:(.*?)").matcher(
parseLine);
if(m.find()) {
for(int i = 0; i < m.groupCount(); ++i) {
System.out.println(m.group(i + 1));
}
}
Matcher m2 = Pattern.compile("Attribute:(\\d+)").matcher(parseLine);
while(m2.find()) {
System.out.println("Attribute matched: " + m2.group(1));
}
But that depends if thre is no Attribute: names before "real" attributes (for example as method name - after p)
You can use the Scanner class. It has some helper methods to read text files
I would turn this inside out. Presently you are:
Scanning the line for a keyword: the entire line if it isn't found, which is the usual case as you have a number of keywords to process and they won't all be present on every line.
Scanning the entire line again for ':' and splitting it on all occurrences
Mostly parsing the part after ':' as an integer, or occasionally as a range.
So several complete scans of each line. Unless the file has zillions of lines this isn't a concern in itself but it demonstrates that you have got the processing back to front.