How to make a local variable accessible outside the loop in java - java

I have a txt file in while one line is like this :
"Execution Status: Pass"
I want to take the value out : pass from here.
I am using below code :
String patternString1 = "(Execution) (Status:) (.*)";
Pattern patt1 = Pattern.compile( patternString1 );
BufferedReader r = new BufferedReader(new FileReader( "c:\\abc.txt" ));
String line;
while ( (line = r.readLine()) != null ) {
String g11 = null;
Matcher m1 = patt1.matcher( line );
while ( m1.find() ) {
g11=m1.group(3);
System.out.println(g11+"HI1"); //Line1
}
System.out.println(g11+"HI1"); //Line2
}
While Line 1 is giving the desired output as "pass" I am not getting this expected output from Line 2.
Could any one of you please help me in accessing the local variable out of the loop?

Declare String g11 as a local variable at the start of your method
String g11=""; -- declare g11 as a local variable
String patternString1 = "(Execution) (Status:) (.*)";
Pattern patt1 = Pattern.compile(patternString1);
Add the rest of your code here.........

Could you try changing following line:
while (m1.find())
to
if(m1.find())
It should give the result you want

How about the easy way:
String result = line.replaceAll(".*: ", "");
This line says "replace everything up to and including colon space with nothing" (ie delete it).

If there is only one instance of this match in single line then use if instead of while (m1.find()) loop or break the loop once match is found.
Sample code:
while ( (line = r.readLine()) != null ) {
String g11 = null;
Matcher m1 = patt1.matcher( line );
if( m1.find() ) {
g11=m1.group(3);
}
if(g11 != null){
System.out.println(g11+"HI1"); //Line2
}
}

Related

Getting substring of a string that has a repeating character Java

I'm a writing a parser that will extract the tag and value out of a line that it reads from a file and I want to know how to get the value. So in this case I want to get
key = "accountName" and
value = "fname LName" and have it repeat with each line.
<accountName>fname LName</accountName>
<accountNumber>12345678912</accountNumber>
<accountOpenedDate>20200218</accountOpenedDate>
This is my code, this is within a while loop that is scanning each line using bufferedReader. I managed to get the key properly, but when I try to get the value, I get "String index out of range - 12. Not sure how to get the value between the two arrows > <.
String line;
if(line.startsWith("<"){
key = line.substring(line.indexOf("<"+1, line.indexOf(">"));
value = line.substring(line.indexOf(">"+1, line.indexOf("<")+1);
}
Though it is recommended to use XML parser but still if you want to do it by manually processing the string at each line:
(using regular expression is recommended to process line) but if you want todo manually with substring way here is the example:
private static void readKeyValue(String line) {
String key = null;
String value = null;
if (null != line && line.startsWith("<") && line.contains("</")) {
key = line.substring(line.indexOf("</")+ 2 , line.lastIndexOf(">"));
value = line.substring(line.indexOf(">") + 1, line.indexOf("</"));
}
System.out.println("key: "+ key);
System.out.println("value: "+ value);
}
You can use regular expressions to extract, assuming the line variable is a string read from each line.
String pattern = "<([a-zA-Z]+.*?)>([\\s\\S]*?)</[a-zA-Z]*?>";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
// find
if (m.find()) {
String key = m.group(1);
String value = m.group(2);
System.out.println("Key: " + key);
System.out.println("Value: " + value);
} else {
System.out.println("Invalid");
}

Unable to find pattern in Java

I have been trying to use pattern matcher to find the specific pattern and I have created the regex pattern through this website and it shows that the pattern is found in the text file I wanted to read.
Extra info.: This code works like this : Start reading the textfile,
when meet >D10, enter another loop and get the information until the
next >D10 is found. Loop this process until EOF.
My sample text file:
D14*
Y7620D03*
X247390Y66680D03*
X251540Y160150D03*
G01Y136780*
G03X-374970Y133680I3100J0*
D17*
Y7620D03*
X247390Y66680D03*
X251540Y160150D03*
G01Y136780*
G03X-374970Y133680I3100J0*
My pattern code in java:
private final Pattern PinNamePattern = compile("(D[1-9][0-9])\\*");
private final Pattern LocationXYPattern = compile("^(G0[1-3])?(X|Y)(-?[\\d]+)(D0[1-3])?\\*",Pattern.MULTILINE);
private final Pattern LocationXYIJPattern = compile("^(G0[1-3])?X(-?[\\d]+)?Y(-?[\\d]+)?I?(-?[\\d]+)?J?(-?[\\d]+)?(D0[1-3])?\\*",Pattern.MULTILINE);
My code in java:
while ((line = br.readLine()) != null) {
Matcher pinNameMatcher = PinNamePattern.matcher(line);
//If found Aperture Name
if (pinNameMatcher.find()) {
currentApperture = pinNameMatcher.group(1);
System.out.println(currentApperture);
pinNameMatcher.reset();
//Start matching Location X Y I J
//Will keep looping as long as next aperture name not found
//Second While loop
while (!(pinNameMatcher.find()) ) {
line = br.readLine();
Matcher locXYMatcher = LocationXYPattern.matcher(line);
Matcher locXYIJMatcher = LocationXYIJPattern.matcher(line);
LineNumber++;
if (locXYMatcher.find()) {
System.out.println("XY FOUND");
if (locXYIJMatcher.find()) {
System.out.println("XYIJ FOUND");
}
}
However, when I'm using java to read, the pattern just simply cannot be found. Is there anything I missed out or am I doing it wrong? I have tried removing the "^" and MULTILINE flag but the pattern is still not found.
Your regex looks and works fine, it's possible you aren't searching it properly.
String s = "G03X-374970Y133680I3100J0*";
Pattern pattern = Pattern.compile("^(G0[1-3])?X(-?[\\d]+)?Y(-?[\\d]+)?I?(-?[\\d]+)?J?(-?[\\d]+)?(D0[1-3])?\\*");
Matcher m = pattern.matcher(s);
while (m.find()) {
String s = m.group(0);
System.out.println(s); // prints G03X-374970Y133680I3100J0*
}
In your updated code, you are looking for the second and third pattern only when the first pattern matches, which is probably not what you want. Try using this as a foundation and improving upon it:
while ((line = br.readLine()) != null) {
Matcher pinNameMatcher = PinNamePattern.matcher(line);
if (pinNameMatcher.find()) {
currentApperture = pinNameMatcher.group(0);
System.out.println(currentApperture);
}
Matcher locXYMatcher = LocationXYPattern.matcher(line);
if (locXYMatcher.find()) {
System.out.println(locXYMatcher.group(0));
}
Matcher locXYIJMatcher = LocationXYIJPattern.matcher(line);
if (locXYMatcher.find()) {
System.out.println(locXYIJMatcher.group(0));
}
}

Buffered Reader: Reset won't reset

I'm currently learing about the mark() and reset() methods of the BufferedReader and want to do the following:
I parse a CSV, set up like this (spaces as delimiter):
555 value1
555 value2
600 foobar
700 whatever
Each line, one object (adress) is created with the first number as its ID. When the ID is used multiple times, I want to compare the values in the second column and proceed afterwards.
With the data above, my code does compare the two values with ID 555, but fails to create an object with the third line (ID 600).
Mistake found: splitted the first line after parsing the new one. Simple mix up of variables.
My setup is similar to this:
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
br.mark(1000); //save current line
List<String> list = new ArrayList<String>(Arrays.asList(line.split(delimiter)));
Adress a = new Adress(Long.parseLong(list.get(0)); //create object
while (((checkLine = br.readLine()) != null) && exit == false){
List<String> nextLine = new ArrayList<String>(Arrays.asList(line.split(delimiter)));
long nextId = Long.parseLong(nextLine.get(0));
if( nextId == a.getId() ){
System.out.println(nextId + " vs. " + a.getId());
br.mark(1000); //mark the next line if it has the same ID
//[...] do more stuff
} else{
exit = true;
}
}
br.reset(); //reset to the last line with the ID
}
Sysout:
555 vs. 555
555 vs. 555
555 vs. 555
I see a couple of issues in the code:
Inside the second while() loop you are still splitting the string "line", but the while loop assigns the input to "checkLine".
You don't reset "exit" to false - this should probably happen after the br.reset().
if your addresses are separated by spaces , and the different elements of your address are also separated by spaces , then this line does not give you addresses , it gives you elements .
List < String > list = new ArrayList < String > ( Arrays . asList ( line . split ( delimiter ) ) ) ;
The mistake was the following variable-mixup (solely my stupidity was the mistake!):
while (((checkLine = br.readLine()) != null) && exit == false){
List<String> nextLine = new ArrayList<String>(Arrays.asList(line.split(delimiter)));
[...]
The List nextLine has to be changed from line.split to checkline.split:
List<String> nextLine = new ArrayList<String>(Arrays.asList(checkLine.split(delimiter)));
Thanks to everybody helping!

Reading Strings from lines in Java

I have a txt file formatted like:
Name 'Paul' 9-years old
How can I get from a "readline":
String the_name="Paul"
and
int the_age=9
in Java, discarding all the rest?
I have:
...
BufferedReader bufferedReader = new BufferedReader(fileReader);
StringBuffer stringBuffer = new StringBuffer();
String line;
while ((line = bufferedReader.readLine()) != null) {
//put the name value in the_name
//put age value in the_age
}
...
Please suggest, thanks.
As you're using BufferedReader and everything is on the one line, you would have to split it to extract the data. Some additional formatting is then required to remove the quotes & extract the year part of age. No need for any fancy regex:
String[] strings = line.split(" ");
if (strings.length >= 3) {
String the_name= strings[1].replace("'", "");
String the_age = strings[2].substring(0, strings[2].indexOf("-"));
}
I notice you have this functionality in a while loop. For this to work, make sure that every line keeps the format:
text 'Name' digit-any other text
^^ ^^ ^
Important chars are
Spaces: min of 3 tokens needed for split array
Single quotes
- Hyphen character
use java.util.regex.Pattern:
Pattern pattern = Pattern.compile("Name '(.*)' (\d*)-years old");
for (String line : lines) {
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
String theName = matcher.group(1);
int theAge = Integer.parseInt(matcher.group(2));
}
}
You can use the String.substring, String.indexOf, String.lastIndexOf, and Integer.parseInt methods as follows:
String line = "Name 'Paul' 9-years old";
String theName = line.substring(line.indexOf("'") + 1, line.lastIndexOf("'"));
String ageStr = line.substring(line.lastIndexOf("' ") + 2, line.indexOf("-years"));
int theAge = Integer.parseInt(ageStr);
System.out.println(theName + " " + theAge);
Output:
Paul 9

using tokenizer to read a line

public void GrabData() throws IOException
{
try {
BufferedReader br = new BufferedReader(new FileReader("data/500.txt"));
String line = "";
int lineCounter = 0;
int TokenCounter = 1;
arrayList = new ArrayList < String > ();
while ((line = br.readLine()) != null) {
//lineCounter++;
StringTokenizer tk = new StringTokenizer(line, ",");
System.out.println(line);
while (tk.hasMoreTokens()) {
arrayList.add(tk.nextToken());
System.out.println("check");
TokenCounter++;
if (TokenCounter > 12) {
er = new DataRecord(arrayList);
DR.add(er);
arrayList.clear();
System.out.println("check2");
TokenCounter = 1;
}
}
}
} catch (FileNotFoundException ex) {
Logger.getLogger(Driver.class.getName()).log(Level.SEVERE, null, ex);
}
}
Hello , I am using a tokenizer to read the contents of a line and store it into an araylist. Here the GrabData class does that job.
The only problem is that the company name ( which is the third column in every line ) is in quotes and has a comma in it. I have included one line for your example. The tokenizer depends on the comma to separate the line into different tokens. But the company name throws it off i guess. If it weren't for the comma in the company column , everything goes as normal.
Example:-
Essie,Vaill,"Litronic , Industries",14225 Hancock Dr,Anchorage,Anchorage,AK,99515,907-345-0962,907-345-1215,essie#vaill.com,http://www.essievaill.com
Any ideas?
First of all StringTokenizer is considered to be legacy code. From Java doc:
StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.
Using the split() method you get an array of strings. While iterating through the array you can check if the current string starts with a quote and if that's the case check if the next one ends with a quote. If you meet these 2 conditions then you know you didn't split where you wanted and you can merge these 2 together, process it like you want and continue iterating through the array normally after that. In that pass you will probably do i+=2 instead of your regular i++ and it should go unnoticed.
You can accomplish this using Regular Expressions. The following code:
String s = "asd,asdasd,asd\"asdasdasd,asdasdasd\", asdasd, asd";
System.out.println(s);
s = s.replaceAll("(?<=\")([^\"]+?),([^\"]+?)(?=\")", "$1 $2");
s = s.replaceAll("\"", "");
System.out.println(s);
yields
asd,asdasd,asd, "asdasdasd,asdasdasd", asdasd, asd
asd,asdasd,asd, asdasdasd asdasdasd, asdasd, asd
which, from my understanding, is the preprocessing you require for your tokenizer-code to work. Hope this helps.
While StringTokenizer might not natively handle this for you, a couple lines of code will do it... probably not the most efficient, but should get the idea across...
while(tk.hasMoreTokens()) {
String token = tk.nextToken();
/* If the item is encapsulated in quotes, loop through all tokens to
* find closing quote
*/
if( token.startsWIth("\"") ){
while( tk.hasMoreTokens() && ! tk.endsWith("\"") ) {
// append our token with the next one. Don't forget to retain commas!
token += "," + tk.nextToken();
}
if( !token.endsWith("\"") ) {
// open quote found but no close quote. Error out.
throw new BadFormatException("Incomplete string:" + token);
}
// remove leading and trailing quotes
token = token.subString(1, token.length()-1);
}
}
As you can see, in the class description, the use of StringTokenizer is discouraged by Oracle.
Instead of using tokenizer I would use the String split() method
which you can use a regular expression as argument and significantly reduce your code.
String str = "Essie,Vaill,\"Litronic , Industries\",14225 Hancock Dr,Anchorage,Anchorage,AK,99515,907-345-0962,907-345-1215,essie#vaill.com,http://www.essievaill.com";
String[] strs = str.split("(?<! ),(?! )");
List<String> list = new ArrayList<String>(strs.length);
for(int i = 0; i < strs.length; i++) list.add(strs[i]);
Just pay attention to your regex, using this one you're assuming that the comma will be always between spaces.

Categories