I have this String: "player.login name=username;x=52;y=406" how would I be able to split it so I easily could do Player pl = new Player(name, x, y) ?
I tried with a regex that looks like this: "([a-zA-Z_]+)[=]{1}([a-zA-Z0-9_]+)[;]{1}" but I'm not very good at regexs so it didn't work.
EDIT: Someone came up with a good solution so no need to comment. :)
What I used:
public static void main(String args[]) {
String login = "player.login name=username;x=52;y=406";
String str = login.substring("player.login".length() + 1);
String[] sp = str.split(";");
Player player = new Player("", 0, 0);
for (String s : sp) {
String[] a = s.split("=");
if (a[0].equals("name")) player.username = a[1];
else if (a[0].equals("x")) player.x = toInt(a[1]);
else if (a[0].equals("y")) player.y = toInt(a[1]);
}
System.out.println("Player: " + player.username + " # " + player.x + ", " + player.y);
}
public static int toInt(String s) {
return Integer.parseInt(s);
}
This should work (you should add bound checks before calling exp.split("=")[1]):
public static void main(String[] args) {
String s = "player.login name=username;x=52;y=406";
String[] expressions = s.split(";");
for (String exp : expressions) {
System.out.println(exp.split("=")[1]);
}
}
Since Java 7 there is support for named capturing groups, would be a nice usage here
String s = "player.login name=username;x=52;y=406";
Pattern p = Pattern.compile("name=(?<UserName>[^;]+);" + // Match the UserName in the Named Group "UserName", matching at least one non semicolon
"x=(?<x>\\d+);" + // Match the value of x in the Named Group "x", matching at least one digit
"y=(?<y>\\d+)" // Match the value of y in the Named Group "y", matching at least one digit
);
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println(m.group("UserName"));
System.out.println(m.group("x"));
System.out.println(m.group("y"));
}
You could use String.split() three times, splitting on a space, then semicolon, then =. Or assylia's answer does it with two splits - best solution rather depends on whether you want to validate the parts of the text you are discarding.
Or using regex...
String regex = ".+=(\\w+);x=(\\d+);y=(\\d+)"
...which you can run with the following code:
Pattern p = Pattern.compile(".+=(\\w+);x=(\\d+);y=(\\d+)");
Matcher m = p.matcher("player.login name=username;x=52;y=406");
m.find();
System.out.println(m.group(1) + "," + m.group(2) + "," + m.group(3));
Or you can try with Guava:
String data = "player.login name=username;x=52;y=406";
List<String> fields = ImmutableList.copyOf(Splitter.on(' ').limit(2).split(data));
String type = fields.get(0);
Map<String, String> properties = Splitter.on(';').trimResults().withKeyValueSeparator("=").split(fields.get(1));
Try using a Pattern instead:
public static void main(String args[]){
String str = "player.login name=username;x=52;y=406";
Pattern p = Pattern.compile("^player\\.login name=(.+);x=(\\d+);y=(\\d+)$");
Matcher m = p.matcher(str);
Player player;
if (m.matches()){
String name = m.group(1);
int x = Integer.parseInt(m.group(2));
int y = Integer.parseInt(m.group(3));
System.out.println(name);
System.out.println(x);
System.out.println(y);
player = new Player(name, x, y);
} else {
player = null;
}
// Do stuff with player.
}
Related
I have a string format like this which is output of
readAllBytes(new String(Files.readAllBytes(Paths.get(data))
from a file
a+2 b+3 c+33 d+88 ......
My scenario is I want to get the data after c+" ". The position of c is not constant but c occurs only once. It may occur anywhere. My required value will always be after c+ only. The required size of value 33.....is also not constant. Can someone help me with the optimal code please? I think collections need to be used here.
You can use this regex which will let you capture the data you want,
c\+(\d+)
Explanation:
c+ matches a literal c character immediately followed by a + char
(\d+) captures the next digit(s) which you are interested in capturing.
Demo, https://regex101.com/r/jfYUPG/1
Here is a java code for demonstrating same,
public static void main(String args[]) {
String s = "a+2 b+3 c+33 d+88 ";
Pattern p = Pattern.compile("c\\+(\\d+)");
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println("Data: " + m.group(1));
} else {
System.out.println("Input data doesn't match the regex");
}
}
This gives following output,
Data: 33
This code is extracting the value right after c+ up to the next space, or to the end of the string if there is no space:
String str = "a+2 b+3 c+33 d+88 ";
String find = "c+";
int index = str.indexOf(" ", str.indexOf(find) + 2);
if (index == -1)
index = str.length();
String result = str.substring(str.indexOf(find) + 2, index);
System.out.println(result);
prints
33
or in a method:
public static String getValue(String str, String find) {
int index = str.indexOf(find) + 2;
int indexSpace = str.indexOf(" ", index);
if (indexSpace == -1)
indexSpace = str.length();
return str.substring(index, indexSpace);
}
public static void main(String[] args) {
String str = "a+2 b+3 c+33 d+88 ";
String find = "c+";
System.out.println(getValue(str, find));
}
I was trying to get an int (serial number of a student) from a string looks like "122. Fardinabir 170213" , where "122" is his serial number.
Before this, I tried using nextInt() method with a Scanner of the String, but nextInt() failed to do the job.
Then I have tried this procces...
import java.util.Scanner;
public class tempfile {
public static void main(String[] args) {
int serial_int = 0;
String serial_st;
serial_st = find_serial("122. FardinAbir 170213") ;
System.out.println(serial_st);
serial_int = Integer.parseInt(serial_st);
System.out.println(serial_int);
}
public static String find_serial(String st)
{
String[] parts = st.split(" "); // the first serial part will remain in parts[0]
parts[0].replaceAll("[\\D]", ""); // As I know it will remove non integer and the pure int serial will remain
return parts[0];
}
}
But, replaceAll("[\\D]", "") is not working...
Can anyone please help me to solve this or find a way out to this job...
Thanks in advance...
String line = "122. FardinAbir 170213";
Pattern pattern = Pattern.compile("^(\\d+)");
Matcher matcher = pattern.matcher(line);
if(matcher.find()) {
int id = Integer.parseInt(matcher.group(1));
System.out.println(id);
}
Assuming you also want to get the rest of the string eventually you can use Regex groups
String line = "122. FardinAbir 170213";
Pattern pattern = Pattern.compile("(\\d+)\\.\\s+([^\\s]+)\\s+(\\d+)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
System.out.println("serial: " + matcher.group(1));
int serial = Integer.parseInt(matcher.group(1));
System.out.println("group 2: " + matcher.group(2));
System.out.println("group 3: " + matcher.group(3));
}
nextInt() probably did not work because scanner expects newline separation
Since you tried using nextInt it seems you just want leading digits, which means you can use the following regex code:
public static String find_serial(String st) {
Matcher m = Pattern.compile("^\\d+").matcher(st);
return (m.find() ? m.group() : null);
}
You could also rely in the serial ending with a period, though that doesn't validate that serial is all digits:
public static String find_serial(String st) {
int idx = st.indexOf('.');
return (idx > 0 ? st.substring(0, idx) : null);
}
This'll do:
public static int getSerialNumber() {
String id = "122. Fardinabir 170213";
int place = 0;
for(int i = 0; i < id.length();i++) {
if(id.charAt(i) == '.') {
place = i;
break;
}
}
return Integer.parseInt(id.substring(0, place));
}
EDIT: you can also do it like this:
public static int getSerialNumber(String name) {
return Integer.parseInt(name.substring(0, name.indexOf('.')));
}
thanks #Andreas for that solution.
My task is splitting a string, which starts with numbers and contains numbers and letters, into two sub-strings.The first one consists of all numbers before the first letter. The second one is the remained part, and shouldn't be split even if it contains numbers.
For example, a string "123abc34de" should be split as: "123" and "abc34de".
I know how to write a regular expression for such a string, and it might look like this:
[0-9]{1,}[a-zA-Z]{1,}[a-zA-Z0-9]{0,}
I have tried multiple times but still don't know how to apply regex in String.split() method, and it seems very few online materials about this. Thanks for any help.
you can do it in this way
final String regex = "([0-9]{1,})([a-zA-Z]{1,}[a-zA-Z0-9]{0,})";
final String string = "123ahaha1234";
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
matcher.group(1) contains the first part and matcher.group(2) contains the second
you can add it to a list/array using these values
You can use a pretty simple pattern : "^(\\d+)(\\w+)" which capture digits as start, and then when letters appear it take word-char
String string = "123abc34de";
Matcher matcher = Pattern.compile("^(\\d+)(\\w+)").matcher(string);
String firstpart = "";
String secondPart = "";
if (matcher.find()) {
firstpart = matcher.group(1);
secondPart = matcher.group(2);
}
System.out.println(firstpart + " - " + secondPart); // 123 - abc34de
This is not the correct way but u will get the result
public static void main(String[] args) {
String example = "1234abc123";
int index = 0;
String[] arr = new String[example.length()];
for (int i = 0; i < example.length(); i++) {
arr = example.split("");
try{
if(Integer.parseInt(arr[i]) >= 0 & Integer.parseInt(arr[i]) <= 9){
index = i;
}
else
break;
}catch (NumberFormatException e) {
index = index;
}
}
String firstHalf = example.substring(0,Integer.parseInt(arr[index])+1);
String secondHalf = example.substring(Integer.parseInt(arr[index])+1,example.length());
System.out.println(firstHalf);
System.out.println(secondHalf);
}
Output will be: 1234 and in next line abc123
Problem: Java program to split the coefficients from a quadratic equation eg
if input string is:
String str1;
str1 = "4x2-4x-42=0"
So I need to split the coefficients from the given input string and to get output as
a = 4 b = -4 c = -42
I tried this:
String equation = "ax2+bx-c=0";
String[] parts = equation.split("\\+|-|=");
for (int i = 0; i < parts.length - 2; i++) {
String part = parts[i].toLowerCase();
System.out.println(part.substring(0, part.indexOf("x")));
}
System.out.println(parts[2]);
But I got the output as 23x2 and 4x and 4.
Actual output needed is 23 ,- 4 , 4.
Use Regex, the following pattern will work:
([+-]?\d+)[Xx]2\s*([+-]?\d+)[Xx]\s*([+-]?\d+)\s*=\s*0
This will match the quadratic and extract the parameters, lets work out how it works:
(...) this is capturing group
[+-]?\d+ this matches a number of digits, preceded optionally by a + or -
[Xx] this matches "X" or "x"
\s* this matches zero or more spaces
So
([+-]?\d+) matches the "a" argument
[Xx]2 matches "X2" or "x2"
\s* matches optional whitespace
([+-]?\d+) matches the "b" argument
[Xx] matches "X" or "x"
\s* matches optional whitespace
([+-]?\d+) matches the "c" argument
\s*=\s*0 matches "=0" with some optional spaces
Lets wrap this in a class:
private static final class QuadraticEq {
private static final Pattern EQN = Pattern.compile("([+-]?\\d+)[Xx]2\\s*([+-]?\\d+)[Xx]\\s*([+-]?\\d+)\\s*=\\s*0");
private final int a;
private final int b;
private final int c;
private QuadraticEq(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static QuadraticEq parseString(final String eq) {
final Matcher matcher = EQN.matcher(eq);
if (!matcher.matches()) {
throw new IllegalArgumentException("Not a valid pattern " + eq);
}
final int a = Integer.parseInt(matcher.group(1));
final int b = Integer.parseInt(matcher.group(2));
final int c = Integer.parseInt(matcher.group(3));
return new QuadraticEq(a, b, c);
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("QuadraticEq{");
sb.append("a=").append(a);
sb.append(", b=").append(b);
sb.append(", c=").append(c);
sb.append('}');
return sb.toString();
}
}
Note the \\, this is required by Java.
A quick test:
System.out.println(QuadraticEq.parseString("4x2-4x-42=0"));
Output:
QuadraticEq{a=4, b=-4, c=-42}
If you are only using quadratics:
int xsqrd = equation.indexOf("x2");
int x = equation.indexOf("x", xsqrd);
int equ = equation.indexOf("=");
String a = equation.subString(0,xsqrd);
String b = equation.subString(xsqrd+1,x);
String c = equation.subString(x,equ);
I may have messed up the substrings but you get the general idea.
The first note: if you use symbol as delimiter in regexp, you will lose it in slpitted elements. I suggest you use the folllowing regexp:
"x2|x|="
Then, you can got only numbers.
The full fragment of code is:
public class Main {
private static final char[] varNames = {'a', 'b', 'c'};
public static void main(String[] args) {
String equation = "4x2-4x-42=0";
String[] parts = equation.split("x2|x|=");
// you will get 4 elements, but the last element is always 0
for(int i=0; i<parts.length - 1; i++){
System.out.println(varNames[i] + " = " + Integer.parseInt(parts[i]));
}
}
}
But in this case you will have the '+' symbols in output. To avoid it, you may use Integer.parseInt(parts[i]) instead of parts[i].
for ( int i = 0 ; i < str.length ; ++i ){
if(asciiOf(str.charAt(i)) == asciiOfIntegerValue ){
addCharInArrayList(str.charAt(i));
}else{
addInFuncList();
addCharInArrayList("_");
}
// join numbers which are not separated by _ and apply BODMAS rule and solve it
// fyi : apologies - very inefficient pseudocode, wrote in a haste
You can use a regex as follows:
final String regex = "([+-]?\\d+)x2([+-]\\d+)x([+-]\\d+)=0";
Pattern pattern = Pattern.compile(regex);
final String equation = "4x2-4x-42=0";
Matcher matcher = pattern.matcher(equation);
if (matcher.matches()) {
int a = Integer.parseInt(matcher.group(1));
int b = Integer.parseInt(matcher.group(2));
int c = Integer.parseInt(matcher.group(3));
System.out.println("a=" + a + " b=" + b + " c=" + c);
}
Output:
a=4 b=-4 c=-42
I am attempting to split a word from its punctuation:
So for example if the word is "Hello?". I want to store "Hello" in one variable and the "?" in another variable.
Here is my code so far:
String inWord = "hello?";
if (inWord.contains(","+"?"+"."+"!"+";")) {
String parts[] = inWord.split("\\," + "\\?" + "\\." + "\\!" + "\\;");
String word = parts[0];
String punctuation = parts[1];
} else {
String word = inWord;
}
System.out.println(word);
System.out.println(punctuation);
My problem is that I am getting error: cannot find symbol when I try and print out the word and the punctuation.
Thanks for help in advance
There are other things wrong with your code but your question was why you get the 'cannot find symbol' error.
String inWord = "hello?";
String word;
String punctuation = null;
if (inWord.contains(","+"?"+"."+"!"+";")) {
String parts[] = inWord.split("\\," + "\\?" + "\\." + "\\!" + "\\;");
word = parts[0];
punctuation = parts[1];
} else {
word = inWord;
}
System.out.println(word);
System.out.println(punctuation);
The scope of a variable declaration like String word = ... is only the block (the pieces of code inside '{' and '}') that it's in. The variables word and punctuation don't exist in the scope in which you try to print them.
You need to declare your variables word and punctuation in the same scope (or an enclosing scope) of where you access them in your System.out.println
You made the following errors in your code.
1.Declare the string outside the if condition
2.inWord.contains(","+"?"+"."+"!"+";") this is equal to inword.contains(",?.!;") , so the condition will fail always and it goes to else condition
split() will not store the value based on which you split the string
eg
String string = "004-034556";
String[] parts = string.split("-");
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556
In this the value "-" can't be stored.Hope you understand what i'm trying to convey.
You could try with your custom contains function and StringTokenizer
as:
public class Test{
public static void main(String[] args) {
String inWord = "hello";
String[] wordAndPunctuation = null;
char[] punctuations =new char[]{',','?','.','!',';'};
StringTokenizer tokenizer = new StringTokenizer(inWord,new String(punctuations),true);
int i = 0;
if (Test.contains(inWord,punctuations)) {
while(tokenizer.hasMoreTokens()){
wordAndPunctuation = new String[tokenizer.countTokens()];
System.out.println(tokenizer.countTokens());
wordAndPunctuation[i] = tokenizer.nextToken();
i++;
}
}else{
System.out.println("No punctuation in "+inWord);
}
}
public static boolean contains(String str, char[] charArr){
System.out.println(Arrays.toString(charArr));
for(char c:charArr){
if(str.contains(String.valueOf(c)))
return true;
}
return false;
}
}
I would recommend parsing through the String and checking if the character is a punctuation method:
String sentence = "Hello? Is this Mrs. Doubtfire?"; // Example.
ArrayList<String> chunks = new ArrayList<>(); // Will store the "non-punctuated chunks"
ArrayList<Character> puncts = new ArrayList<>();// Will the punctuations in the "sentence"
char[] punctuations = {',','?','.','!',';'}; // Store punctuations here.
int lastIndex = 0;
for (int i = 0; i < sentence.length(); i++) {
char c = sentence.charAt(i);
for (char punctuation : punctuations) {
if (c == punctuation) {
chunks.add(sentence.substring(lastIndex, i).trim());
puncts.add(c);
lastIndex = i + 1;
}
}
}
System.out.println(chunks);
System.out.println(puncts);
Output:
[Hello, Is this Mrs, Doubtfire]
[?, ., ?]
And remember to import java.util.ArrayList!
Why don't you do this:
String s = "hello!";
Pattern p = Pattern.compile("(\\w+)?(\\W)");
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println("Word: " + m.group(1) + " | Punctuation: " + m.group(2));
}
Group1 will contain the word and Group2 will contain the punctuation.
Demo : http://ideone.com/ljIZFW