Java parse string using regex into variables - java

I need to extract variables from a string.
String format = "x:y";
String string = "Marty:McFly";
Then
String x = "Marty";
String y = "McFly";
but the format can be anything it could look like this y?x => McFly?Marty
How to solve this using regex?
Edit: current solution
String delimiter = format.replace(Y, "");
delimiter = delimiter.replaceAll(X, "");
delimiter = "\\"+delimiter;
String strings[] = string.split(delimiter);
String x;
String y;
if(format.startsWith(X)){
x = strings[0];
y = strings[1];
}else{
y = strings[0];
x = strings[1];
}
System.out.println(x);
System.out.println(y);
This works well, but I would prefer more clean solution.

There is no need for regex at all.
public static void main(String[] args) {
test("x:y", "Marty:McFly");
test("y?x", "McFly?Marty");
}
public static void test(String format, String input) {
if (format.length() != 3 || Character.isLetterOrDigit(format.charAt(1))
|| (format.charAt(0) != 'x' || format.charAt(2) != 'y') &&
(format.charAt(0) != 'y' || format.charAt(2) != 'x'))
throw new IllegalArgumentException("Invalid format: \"" + format + "\"");
int idx = input.indexOf(format.charAt(1));
if (idx == -1 || input.indexOf(format.charAt(1), idx + 1) != -1)
throw new IllegalArgumentException("Invalid input: \"" + input + "\"");
String x, y;
if (format.charAt(0) == 'x') {
x = input.substring(0, idx);
y = input.substring(idx + 1);
} else {
y = input.substring(0, idx);
x = input.substring(idx + 1);
}
System.out.println("x = " + x);
System.out.println("y = " + y);
}
Output
x = Marty
y = McFly
x = Marty
y = McFly
If the format string can be changed to be a regex, then using named-capturing groups will make it very simple:
public static void main(String[] args) {
test("(?<x>.*?):(?<y>.*)", "Marty:McFly");
test("(?<y>.*?)\\?(?<x>.*)", "McFly?Marty");
}
public static void test(String regex, String input) {
Matcher m = Pattern.compile(regex).matcher(input);
if (! m.matches())
throw new IllegalArgumentException("Invalid input: \"" + input + "\"");
String x = m.group("x");
String y = m.group("y");
System.out.println("x = " + x);
System.out.println("y = " + y);
}
Same output as above, including value order.

You can use the following regex (\\w)(\\W)(\\w)
This will find any alphanumeric characters followed by any non alpha-numeric followed by another set of alpha numeric characters. The parenthesis will group the finds so group 1 will be parameter 1, group 2 will be the delimiter and group 3 will be parameter 2.
Comparing parameter 1 with parameter 2 can determine which lexical order they go in.
Sample
public static void main(String[] args) {
testString("x:y", "Marty:McFly");
testString("x?y", "Marty?McFly");
testString("y:x", "Marty:McFly");
testString("y?x", "Marty?McFly");
}
/**
*
*/
private static void testString(String format, String string) {
String regex = "(\\w)(\\W)(\\w)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(format);
if (!matcher.find()) throw new IllegalArgumentException("no match found");
String delimiter = matcher.group(2);
String param1 = matcher.group(1);
String param2 = matcher.group(3);
String[] split = string.split("\\" + delimiter);
String x;
String y;
switch(param1.compareTo(param2)) {
case 1:
x = split[1];
y = split[0];
break;
case -1:
case 0:
default:
x = split[0];
y = split[1];
};
System.out.println("String x: " + x);
System.out.println("String y: " + y);
System.out.println(String.format("%s%s%s", x, delimiter, y));
System.out.println();
}
This approach will allow you to have any type of format not just x and y. You can have any format that matches the regular expression.

Related

How to remove one charachter from a string

With the scanner I want to read the index of a char and then remove it from the string. There is only one problem: If the char comes multiple times in the string, .replace() removes all of them.
For example I want to get the index of first 't' from the String "Texty text" and then remove only that 't'. Then I want to get index of second 't' and then remove it.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
String text = "Texty text";
Scanner sc = new Scanner(System.in);
int f = 0;
int x = 0;
while(f<1){
char c = sc.next().charAt(0);
for(int i = 0; i<text.length();i++){
if(text.charAt(i)==c){
System.out.println(x);
x++;
}
else{
x++;
}
}
}
System.out.println(text);
}
}
You could use replaceFirst:
System.out.println(text.replaceFirst("t", ""));
Probably you are looking for something like the following:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String text = "Texty text";
String copy = text;
Scanner sc = new Scanner(System.in);
while (true) {
text = copy;
System.out.print("Enter a character from '" + text + "': ");
char c = sc.next().charAt(0);
for (int i = 0; i < text.length(); i++) {
if (Character.toUpperCase(text.charAt(i)) == Character.toUpperCase(c)) {
System.out.println(c + " was found at " + i);
text = text.substring(0, i) + "%" + text.substring(i + 1);
System.out.println("After replacing " + c + " with % at " + i + ": " + text);
}
}
}
}
}
A sample run:
Enter a character from 'Texty text': x
x was found at 2
After replacing x with % at 2: Te%ty text
x was found at 8
After replacing x with % at 8: Te%ty te%t
Enter a character from 'Texty text': t
t was found at 0
After replacing t with % at 0: %exty text
t was found at 3
After replacing t with % at 3: %ex%y text
t was found at 6
After replacing t with % at 6: %ex%y %ext
t was found at 9
After replacing t with % at 9: %ex%y %ex%
Enter a character from 'Texty text':
Try using txt.substring(x,y)
x = usually 0 , but x is first start index
y = this is what you want to delete for example for the last word of string write this code:
txt.substring(0, txt.length() - 1)
Since you are specifying indices, it is possible that you may want to replace the second of a particular character. This does just that by ignoring the ones before it. This returns an Optional<String> to encase the result. Exceptions are thrown for appropriate situations.
public static void main(String[] args) {
// Replace the first i
Optional<String> opt = replace("This is a testi", 1, "i", "z");
// Replace the second i (and so on).
System.out.println(opt.get());
opt = replace("This is a testi", 2, "i", "z");
System.out.println(opt.get());
opt = replace("This is a testi", 3, "i", "z");
System.out.println(opt.get());
opt = replace("This is a testi", 4, "i", "z");
System.out.println(opt.get());
}
public static Optional<String> replace(String str, int occurrence, String find, String repl) {
if (occurrence == 0) {
throw new IllegalArgumentException("occurrence <= 0");
}
int i = -1;
String strCopy = str;
while (occurrence-- > 0) {
i = str.indexOf(find, i+1);
if (i < 0) {
throw new IllegalStateException("insufficient occurrences of '" + find + "'");
}
}
str = str.substring(0,i);
return Optional.of(str + strCopy.substring(i).replaceFirst(find, repl));
}

CharAt(0) out of bounds exception when I have too much white space

Currently stuck on an assignment that requires me to print out the users name as such: Last,First Initial.
(Bob, Billy H.) If I add too many spaces between the first and middle name when inputting, I get an index out of bounds exception. (String out of bounds 0) The program runs completely fine unless I have more than one space between the first and middle name.
I can only use the trim, indexOf, substring,and charAt methods in this program.
import java.util.Scanner;
public class Name {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Enter your name in this format: <spaces>First name<spaces>Middle name<spaces>Last name<spaces>");
String name = s.nextLine();
name = name.trim();
String first, middle, last;
int firstSpace = name.indexOf(' ');
first = name.substring(0, firstSpace);
int secondSpace = name.indexOf(" ", (firstSpace + 1));
middle = name.substring((firstSpace + 1), secondSpace);
middle.trim();
last = name.substring(secondSpace+1);
char middleInitial = middle.charAt(0);
String initial = "";
initial = initial + middleInitial;
for(int i = 1; i < middle.length(); i++) {
char currentLetter = middle.charAt(i);
char lastLetter = middle.charAt(i - 1);
if(lastLetter == ' ') {
initial = initial + "." + currentLetter;
}
}
System.out.println(last + "," + first + ' ' + initial + ".");
}
}
The reason for error is for input
amid skum asdf
for above input:
int firstSpace = name.indexOf(' '); //firstSpace = 0
int secondSpace = name.indexOf(" ", (firstSpace + 1));//secondSpace = 1
middle = name.substring((firstSpace + 1), secondSpace); // as the two or more continues space inputted, this will select empty string as firstSpace + 1 == secondSpace and later causing the exception
Do name = name.replaceAll(" +", " "); to replace all two or more white spaces.
As karthik suggested in comments, perform assignment middle = middle.trim();.
EDIT:
Since you can not use replaceAll, Modified the code just by using trim method. Have a closer look at the below snippets:
String middleNameLastName = name.substring(firstSpace+1).trim();
last = middleNameLastName.substring(index+1).trim();
These removes trailing spaces.
import java.util.Scanner;
public class Post1 {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Enter your name in this format: <spaces>First name<spaces>Middle name<spaces>Last name<spaces>");
String name = s.nextLine();
name = name.trim();
String first, middle, last;
int firstSpace = name.indexOf(' ');
first = name.substring(0, firstSpace);
String middleNameLastName = name.substring(firstSpace+1).trim();
int index = middleNameLastName.indexOf(" ");
middle = middleNameLastName.substring(0, index);
last = middleNameLastName.substring(index+1).trim();
System.out.println(last + "," + first + ' ' + middle.charAt(0) + ".");
s.close();
}
}

How to integrate a loop in my code

I am new to Java. My program first gets inputs from the user about their car, and then it shows the result.
I need to integrate my "Rövarspråk" in to the code, but I am not really sure how.
If the user owns a "Saab" or a "Volvo" the "rövarspråk" loop should change the user's "string name".
If something is unclear, just tell me and I'll try to explain better.
Thanks in advance.
public static void main(String[] args) {
String lookSaab;
String consonantsx;
String input;
String slang;
String add;
// String
int length;
// int
Scanner skriv;
// Scanner
String reg;
String year;
String brand;
String name;
String car;
String when;
String small;
String medium;
String big;
// String
int mod;
int randomNumber;
int quota;
int denominator;
// int
reg = JOptionPane.showInputDialog("Ange registreringsnummer"); // Input plate number of your car
year = JOptionPane.showInputDialog("Ange årsmodell"); // Input model year of the car
mod = Integer.parseInt(year);
brand = JOptionPane.showInputDialog("Ange bilmärke"); //Input car brand
name = JOptionPane.showInputDialog("Ange ägare "
+ "(för - och efternamn)"); //Input owner of the car first name + last name
car = brand + reg;
Date date = new Date();
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("EEE MMM dd");
when = sdf.format(date);
denominator = 1500;
randomNumber = 1500 + (int)(Math.random() * ((40000 - 1500) + 1));
quota = randomNumber / denominator;
small = "Liten service";
medium = "Medium service";
big = "Stor service";
if (randomNumber <= 8000){
JOptionPane.showMessageDialog(null, small, "Typ av service", 1);
} else if ( randomNumber <= 20000){
JOptionPane.showMessageDialog(null, medium, "Typ av service", 1);
} else {
JOptionPane.showMessageDialog(null, big, "Typ av service", 1);
}
String resultat = "Bil: " + car + "\n"
+ "Årsmodell: " + mod + "\n"
+ "Ägare: " + name + "\n"
+ "Mästarställning: " + randomNumber + "\n"
+ "Inlämnad: " + when + "\n"
+ "Klar om: " + quota + " dagar";
JOptionPane.showMessageDialog(null, resultat, "Resulat", 1);
lookSaab = "Saab";
if (brand.equals(lookSaab)){
}
/* Rövarspråket */
consonantsx = "bBcCdDeEfFgGhHjJkKlLmMnNpPqQrRsStTvVwWxXzZ"; //Saves all consonants to string
char consonants[] = consonantsx.toCharArray(); //String to charr
System.out.println("Mata in en mening");
skriv = new Scanner(System.in);
input = skriv.nextLine(); //Saves the input
length = input.length(); //Length inc. space
char array[] = input.toCharArray(); // Input to a char array
slang = "";
System.out.println("På rövarspråk:");
for(int i = 0; i<length; i++) {
for(int x = 0; x<20; x++){
if(array[i] == consonants[x])
{
add = array[i]+"o"+array[i];
slang = slang + add;
break;
}
else{
}
}
}
System.out.println(slang);
}
}
OK so as mentioned a good start would be to put your RoverSpraket translator into its own method:
public String rovarSpraket(String normalString) {
final String consonantsx = "bBcCdDeEfFgGhHjJkKlLmMnNpPqQrRsStTvVwWxXzZ";
char consonants[] = consonantsx.toCharArray(); // String to charr
int length = normalString.length(); // Length inc. space
char array[] = normalString.toCharArray(); // Input to a char array
String slang = "";
System.out.println("På rövarspråk:");
for (int i = 0; i < length; i++) {
for (int x = 0; x < 20; x++) {
if (array[i] == consonants[x]) {
String add = array[i] + "o" + array[i];
slang = slang + add;
break;
} else {
}
}
}
return slang;
}
This method takes a "normal" String as input and returns the Rövarspråk version of it.
Given that it can be used anywhere you want now, like:
/i named my class "Goran" ;)
Goran goran = new Goran(); //instatiate a class object
String hello = "hello world";
System.out.println(goran.rovarSpraket(hello)); //use class object method "roverSpraket"
This will print as the following on the console:
På rövarspråk:
hoheoelollolloldod
Only thing left to do is use this in the remaining code. I guess what you want is that:
if (brand.equals("Saab") || brand.equals("Volvo")){
name = rovarSpraket(name); //translate if brand is Saab or Volvo
}
And a working example for calling the method (one way to do it)
public class Goran {
public static void main(String[] args) {
String brand;
String name;
//i named my class "Goran" ;)
Goran goran = new Goran(); //instatiate a class object
String hello = "hello world";
System.out.println(goran.rovarSpraket(hello)); //use class object method "roverSpraket"
brand = "Saab";
name = "henry";
if (brand.equals("Saab") || brand.equals("Volvo")){
name = goran.rovarSpraket(name); //translate if brand is Saab or Volvo
}
System.out.println("new name is " + name);
}
public String rovarSpraket(String normalString) {
final String consonantsx = "bBcCdDeEfFgGhHjJkKlLmMnNpPqQrRsStTvVwWxXzZ";
char consonants[] = consonantsx.toCharArray(); // String to charr
int length = normalString.length(); // Length inc. space
char array[] = normalString.toCharArray(); // Input to a char array
String slang = "";
System.out.println("På rövarspråk:");
for (int i = 0; i < length; i++) {
for (int x = 0; x < 20; x++) {
if (array[i] == consonants[x]) {
String add = array[i] + "o" + array[i];
slang = slang + add;
break;
} else {
}
}
}
return slang;
}
}
Hope this helps ^^

solving all y values for equations of the format y = mx+c

I am creating a program in which you enter an equation in the format of y = mx+c
It will give the y values from -2 to +2.
An example of something the user may enter is y = 2x+5.
How would I solve this?
I want to input integer values for x
I don't know where or how to start.
If you want to input only integers for the value of x you can use the following method below... The method allows you to chose the value of your gradient and y-intercept.
You could use this method:
public static void rangeCalculator(int startPoint, int endPoint){
Scanner input = new Scanner(System.in);
System.out.print("Enter gradient:");
double gradient = input.nextDouble();
System.out.print("\nEnter intercept:");
double intercept = input.nextDouble();
for(int i=startPoint; i<=endPoint; i++){
System.out.println("y="+gradient+"x + " +intercept+"\t" + "input:"+i + " output:" + (gradient*i + intercept));
}
}
import java.util.Scanner;
public class graphTester {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter equation: ");
String input = scanner.nextLine();
Character equalsChar = '=';
Character xChar = 'x';
int iEquals = 0;
int iX =0;
int iPlusOrSubtract = 0;
int[] xValues = {-2, -1, 0, 1, 2, 3, 4};
int[] yValues = new int[7];
int i = 0;
for (iEquals = 0; iEquals <= input.length(); iEquals++){
Character c1 = input.charAt(iEquals);
if (c1 == equalsChar){
System.out.println("Found equals at index: " + iEquals);
break;
}else{
}
}
for (iX = 0; iX <= input.length(); iX++){
Character c2 = input.charAt(iX);
if (c2 == xChar){
System.out.println("Found x at index: " + iX);
break;
}else{
}
}
String coEfficientString = input.substring(iEquals + 1, iX);
int coEfficient = Integer.parseInt(coEfficientString);
System.out.println("coEfficient: " + coEfficient);
String yInterceptString = input.substring(iX + 1, input.length());
int yIntercept = Integer.parseInt(yInterceptString);
System.out.println("Y-Intercept: " + yIntercept);
for (int value : xValues){
i++;
System.out.println("X-Value:" + value + " Y-Value:" + value*coEfficient);
yValues[i] = value*coEfficient;
}
System.out.println(yValues);
}
}
import java.util.regex.*;
public class RegexTester {
public static void main(String[] args) {
String str2Check = "3x+2";
//Find x - \\d{1,}+[x-x]
//Find y-intercept [[\\+] | [\\-]]+\\d{1}
String regexStringCoefficient = "[[\\+] | [\\-]]+\\d{1}";
regexChecker(regexStringCoefficient, str2Check);
}
public static void regexChecker(String regexString, String str2Check){
Pattern checkRegex = Pattern.compile(regexString);
Matcher regexMacher = checkRegex.matcher(str2Check);
while (regexMacher.find()){
if (regexMacher.group().length() != 0){
System.out.println(regexMacher.group());
System.out.println("First Index: " + regexMacher.start());
System.out.println("Ending index: " + regexMacher.end());
}
}
}
}

Add both string and int value in one JTextField

Convert user input of meters to feet and inches with the
// following format (16ft. 4in.). Disable the button so that
// the user is forced to clear the form.
Problem is that I don't know how to put both string and int value in one text Field, than how can i set them to in if else statement
private void ConversionActionPerformed(ActionEvent e )
{
String s =(FourthTextField.getText());
int val = Integer.parseInt(FifthTextField.getText());
double INCHES = 0.0254001;
double FEET = 0.3048;
double meters;
if(s.equals("in" ) )
{
FourthTextField.setText(" " + val*INCHES + "inch");
}
else if(s.equals("ft"))
{
FourthTextField.setText(" " +val*FEET + "feet");
}
}
Is it possible to add both string and int value in one JTextField?
You could do ...
FourthTextField.setText(" " + (val*INCHES) + "inch");
or
FourthTextField.setText(" " + Double.toString(val*INCHES) + "inch");
or
FourthTextField.setText(" " + NumberFormat.getNumberInstance().format(val*INCHES) + "inch");
Updated
If all you care about is extract the numeric portion of the text, you could do something like this...
String value = "1.9m";
Pattern pattern = Pattern.compile("\\d+([.]\\d+)?");
Matcher matcher = pattern.matcher(value);
String match = null;
while (matcher.find()) {
int startIndex = matcher.start();
int endIndex = matcher.end();
match = matcher.group();
break;
}
System.out.println(match);
This will output 1.9, having stripped of every after the m. This would allow you to extract the numeric element of the String and convert to a number for conversion.
This will handle both whole and decimal numbers.

Categories

Resources