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
Related
This question already has answers here:
Java generating Strings with placeholders
(12 answers)
Closed 4 years ago.
The client passed me a parameter str = "${param0},${param1}".
I want to replace ${param0} ${param1} with the value I queried from the database.
such as
//str = "${param0},${param1}"
//str = "${param0},${param1}, ${param2}"
//...
public String format(String str) {
String param0 = repository.query0();
//expect
str = "param0,${param1}";
String param1 = repository.query1();
//expect
str = "param0,param1,${param2}";
return str;
}
I know that java.lang.String#replace can solve the problem. But the parameter str is indefinite. It could also be str = "${param0}, ${param1}, ${param2}" or more. Is there any way to satisfy my request?
If you can be confident that it will always be in the format of ${paramX} then you can do the following:
String str = ...;
for (int i = 0; i < results.length; i++)
{
str = str.replace("${param" + i + "}", results[i]);
}
Replace the contents of the for loop and the resutls[i] portion to be however you access the data returned from your query.
If you instead can't dependent on ${paramX} being in sequential order, you can use a more hacky solution by using the following code:
// create a new StringBuilder to reduce concatentation
StringBuilder result = new StringBuilder();
// our warped string input
String str = "${param0}, ${param12}${param1234}${param2}";
// split it anywhere that is formatted with ${paramXXXX}
String[] parts = str.split("\\$\\{param[0-9]{1,}\\}");
// loop through the pieces
for (int i = 0; i < parts.length; i++)
{
// get the parts of the string that are not ${paramXXXX}
result.append(parts[i]);
// the results from the query.
result.append(queryResults[i]); // Replace with the proper way to read your query results
}
The above code should work no matter the input, as long as there are the same number of query results as there are ${paramXXXX} pieces in the input string.
Be sure to replace the code followed by // Replace with ... with the code to read your query results.
Here is an approach using matcher:
String str = "${param0},${param1}, ${param2}";
System.out.println("Matching: "+str);
Pattern regex = Pattern.compile("\\$\\{(\\w+)\\}");
Matcher matcher = regex.matcher(str);
while (matcher.find()){
System.out.println("found: "+matcher.group());
str = matcher.replaceFirst("results");
matcher = regex.matcher(str);
}
System.out.println("Result: "+str);
This is not very efficient, but easy to use. If you have gigabyte-scale computations, consider looping over your input string and compare characters manually.
Update:
Here is a better approach. More efficient and not susceptible for endless loop if results contain the pattern.
String str = "[${param0},${param1}, ${param2}]";
System.out.println("Matching: " + str);
final Pattern regex = Pattern.compile("\\$\\{(\\w+)\\}");
final Matcher matcher = regex.matcher(str);
final StringBuilder sb = new StringBuilder(str.length());
int prevMatch = 0;
while (matcher.find()) {
System.out.println("found: " + matcher.group());
sb.append(str.substring(prevMatch, matcher.start()));
sb.append("results");
prevMatch = matcher.end();
}
sb.append(str.substring(prevMatch, str.length()));
System.out.println("Result: " + sb.toString());
We need to find the length of the tag names within the tags in java
{Student}{Subject}{Marks}100{/Marks}{/Subject}{/Student}
so the length of Student tag is 7 and that of subject tag is 7 and that of marks is 5.
I am trying to split the tags and then find the length of each string within the tag.
But the code I am trying gives me only the first tag name and not others.
Can you please help me on this?
I am very new to java. Please let me know if this is a very silly question.
Code part:
System.out.println(
getParenthesesContent("{Student}{Subject}{Marks}100{/Marks}{/Subject}{/Student}"));
public static String getParenthesesContent(String str) {
return str.substring(str.indexOf('{')+1,str.indexOf('}'));
}
You can use Patterns with this regex \\{(\[a-zA-Z\]*)\\} :
String text = "{Student}{Subject}{Marks}100{/Marks}{/Subject}{/Student}";
Matcher matcher = Pattern.compile("\\{([a-zA-Z]*)\\}").matcher(text);
while (matcher.find()) {
System.out.println(
String.format(
"tag name = %s, Length = %d ",
matcher.group(1),
matcher.group(1).length()
)
);
}
Outputs
tag name = Student, Length = 7
tag name = Subject, Length = 7
tag name = Marks, Length = 5
You might want to give a try to another regex:
String s = "{Abc}{Defg}100{Hij}100{/Klmopr}{/Stuvw}"; // just a sample String
Pattern p = Pattern.compile("\\{\\W*(\\w++)\\W*\\}");
Matcher m = p.matcher(s);
while(m.find()) {
System.out.println(m.group(1) + ", length: " + m.group(1).length());
}
Output you get:
Abc, length: 3
Defg, length: 4
Hij, length: 3
Klmopr, length: 6
Stuvw, length: 5
If you need to use charAt() to walk over the input String, you might want to consider using something like this (I made some explanations in the comments to the code):
String s = "{Student}{Subject}{Marks}100{/Marks}{/Subject}{/Student}";
ArrayList<String> tags = new ArrayList<>();
for(int i = 0; i < s.length(); i++) {
StringBuilder sb = new StringBuilder(); // Use StringBuilder and its append() method to append Strings (it's more efficient than "+=") String appended = ""; // This String will be appended when correct tag is found
if(s.charAt(i) == '{') { // If start of tag is found...
while(!(Character.isLetter(s.charAt(i)))) { // Skip characters that are not letters
i++;
}
while(Character.isLetter(s.charAt(i))) { // Append String with letters that are found
sb.append(s.charAt(i));
i++;
}
if(!(tags.contains(sb.toString()))) { // Add final String to ArrayList only if it not contained here yet
tags.add(sb.toString());
}
}
}
for(String tag : tags) { // Printing Strings contained in ArrayList and their length
System.out.println(tag + ", length: " + tag.length());
}
Output you get:
Student, length: 7
Subject, length: 7
Marks, length: 5
yes use regular expression, find the pattern and apply that.
I have an application that suppose to read data from the text file with student details (student.txt), such that I have a studentNo, StudentName, Marks etc. . .
Here is a sample of the data that's in the textfile :
20405587 "ZULU,B M" 65 67
20407388 "JUGGERNATH,N" 66 63
20408427 "KHATHI,P X" 60 60
20409821 "SINGH,T" 62 59
20410422 "NKOMO,N N" 58 60
I'm using a scanner to read from the file, here is my code so far. . .it gives me an error
try
{
BufferedReader br = new BufferedReader(new FileReader("student.txt"));
String line = br.readLine();
while (line!=null)
{
Scanner scan = new Scanner(line);
scan.useDelimiter(" ");
String dummystudent=scan.next();
int studentNo= Integer.parseInt(dummystudent);
String dummyname1 = scan.next();
String dummyname2 = scan.next();
String studentName = dummyname1+dummyname2;
String dummytest1 = scan.next();
int test1= Integer.parseInt(dummytest1);
String dummytest2 = scan.next();
int test2= Integer.parseInt(dummytest2);
tad1.setText(tad1.getText()+"Student Number: " + studentNo + '\n' + "Student Name :" + studentName );
line = br.readLine();
}
br.close();
}
catch(Exception b)
{
JOptionPane.showMessageDialog(null,b.getMessage());
}
You set the delimiter to a single space. This is the problem. next will return an empty string a few times because those lines of yours has more than one consecutive spaces.
Instead you want to say one or more spaces:
sc.useDelimiter(" +");
It's still not 100% since "ZULU,B M" has a space in the middle and "JUGGERNATH,N" doesn't, but I'll leave that to you to figure out. Maybe:
sc.useDelimiter("\"");
somewhere in the middle there.
The + has to do with regular expressions, see this for more in general and this for more Java-specific.
Your parsing seems to be overkill.
Consider using Scanner to read the line and use StringUtils.split() to parse the line.
Here is some code:
public static void main(String[] args)
{
int index = 1; // Just for printing.
for (String current : input)
{
String[] split1; // result: number, name, numbers
String[] split2;
String studentName1;
String studentName2;
String studentNumber;
String testScore1;
String testScore2;
split1 = StringUtils.split(current, '"');
studentNumber = StringUtils.trim(split1[0]);
split2 = StringUtils.split(split1[1], ',');
studentName1 = StringUtils.trim(split2[0]);
studentName2 = StringUtils.trim(split2[1]);
split2 = StringUtils.split(split1[2]); // default seperator is whitespace.
testScore1 = StringUtils.trim(split2[0]);
testScore2 = StringUtils.trim(split2[1]);
System.out.println(
index + ":" +
" Number: " + ">" + studentNumber + "" + studentName1 + "" + studentName2 + "" + testScore1 + "" + testScore2 + "
Note: StringUtils is from Apache Commons Lang
Easiest way to end would to be go line by line.
Pattern filePatten = Pattern.compile("\\s*(\\d+)\\s+(\"[^\"]+\")\\s+(\\d+)\\s+(\\d+)\\s*");
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
Matcher matcher = filePattern.matcher(line);
if (matcher.matches()) {
String id = matcher.group(1);
String name = matcher.group(2);
//etc
} else {
//Warn : Fragile Regex
}
}
Each group in the regex captures a part of the line. The second group captures the name with quotes. You might want to remove it.
You should be using the delimiter "? +"?, the delimiter is a regex, and your string has multiple spaces to separate fields, you also need to take into account quotes around string fields. I'm yet to workout how to solve string fields with spaces.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html#useDelimiter(java.lang.String)
Using Regex you should be able to do it using the below regex string, and select the subgroups 1-4, through a Matcher
([0-9]{8}) +"([A-Z, ]+)" +([0-9]{2}) +([0-9]{2})
right now I am a little bit confused. I want to manipulate this string with a tokenizer:
Bob:23456:12345 Carl:09876:54321
However, I use a Tokenizer, but when I try:
String signature1 = tok.nextToken(":");
tok.nextToken(" ")
I get:
12345 Carl
However I want to have the first int and the second int into a var.
Any ideas?
You have two different patterns, maybe you should handle both separated.
Fist you should split the space separated values. Only use the string split(" "). That will return a String[].
Then for each String use tokenizer.
I believe will works.
Code:
String input = "Bob:23456:12345 Carl:09876:54321";
String[] words = input.split(" ")
for (String word : words) {
String[] token = each.split(":");
String name = token[0];
int value0 = Integer.parseInt(token[1]);
int value1 = Integer.parseInt(token[2]);
}
Following code should do:
String input = "Bob:23456:12345 Carl:09876:54321";
StringTokenizer st = new StringTokenizer(input, ": ");
while(st.hasMoreTokens())
{
String name = st.nextToken();
String val1 = st.nextToken();
String val2 = st.nextToken();
}
Seeing as you have multiple patterns, you cannot handle them with only one tokenizer.
You need to first split it based on whitespace, then split based on the colon.
Something like this should help:
String[] s = "Bob:23456:12345 Carl:09876:54321".split(" ");
System.out.println(Arrays.toString(s ));
String[] so = s[0].split(":", 2);
System.out.println(Arrays.toString(so));
And you'd get this:
[Bob:23456:12345, Carl:09876:54321]
[Bob, 23456:12345]
If you must use tokeniser then I tink you need to use it twice
String str = "Bob:23456:12345 Carl:09876:54321";
StringTokenizer spaceTokenizer = new StringTokenizer(str, " ");
while (spaceTokenizer.hasMoreTokens()) {
StringTokenizer colonTokenizer = new StringTokenizer(spaceTokenizer.nextToken(), ":");
colonTokenizer.nextToken();//to igore Bob and Carl
while (colonTokenizer.hasMoreTokens()) {
System.out.println(colonTokenizer.nextToken());
}
}
outputs
23456
12345
09876
54321
Personally though I would not use tokenizer here and use Claudio's answer which splits the strings.
I have a String
String testString = "IN NEWYORK AND (OUT FLORIDA)" ;
I want to split out this string in array Like :
String testArray[] = testString.split("\\s()");
I would like the result to be:
testArray[0] = "IN";
testArray[1] = "NEWYORK";
testArray[2] = "AND";
testArray[3] = "(";
testArray[4] = "OUT";
testArray[5] = "FLORIDA";
testArray[6] = ")";
However, the output I get is:
testArray[0] = "IN";
testArray[1] = "NEWYORK";
testArray[2] = "AND";
testArray[3] = "(OUT";
testArray[4] = "FLORIDA)";
It is splitting on white spaces but not on "(" and ")" , I want "(" and ")" to be as seperate strings .
Try the below:
String testArray[] = testString.split("\\s|(?<=\\()|(?=\\))");
split() requires a deleimeter to remove. Use StringTokenizer and instruct it to keep the delimiters.
StringTokenizer st = new StringTokenizer("IN NEWYORK AND (OUT FLORIDA)", " ()", true);
while (st.hasMoreTokens()) {
String t = st.nextToken();
if (!t.trim().equals("")) {
System.out.println(t);
}
}
If you want to do it with string split, then monstrous regexes like \s+|((?<=\()|(?=\())|((?<=\))|(?=\))) are pretty much inevitable. This regex is based on this question, btw, and it almost works.
Easiest way is to either surround parentheses with spaces as suggested by #acerisara or use StringTokenizer as suggested by #user1030723
String test = "IN NEWYORK AND (OUT FLORIDA)";
// this can for sure be done better, hope you get the idea
String a = test.replaceAll("(", "( ");
String b = a.replaceAll(")", " )";
String array[] = b.split("\\s");