So I have this string:
String myString = "Welcome, your drive today to the LAX will be (45+ min). Enjoy your drive!";
What is the best way to go about getting the 45 as a separate string? And this string could sometimes have more than one number in it, Example:
String myString = "Welcome, your drive today to the LAX will be (45+ min). You should arrive about (11:10 am). Enjoy your drive!";
But I only want to get the one what has 45+ min and separate out the + min so that 45 is my only string.
This can be easily done using regular expressions.
Java Predefined character classes for regular expressions.
. = Any character (may or may not match line terminators)
\d = A digit: [0-9]
\D = A non-digit: [^0-9]
String myString = "Welcome, your drive today to the LAX will be (45+ min). Enjoy your drive!";
//Replace all non digit characters with empty space so only numbers will be there.
myString = myString.replaceAll("\\D", "");
System.out.println(myString); //this displays only numbers.
So I did figure out my answer after a lot of trial and error. If you have a better way please comment it, I don't mind changing my accepted answer.
String text = "Welcome, your drive today to the LAX will be (45+ min) and the tolls will cost ($2.50). Enjoy your drive!";
tripMiles = getNumberFromString("(?i)(\\d+)\\s+ min", text);
public static double getNumberFromString(String value, final String s)
{
double n = 0.0;
Matcher M = Pattern.compile(value).matcher(s);
while (((Matcher)M).find())
{
try {
n = Double.parseDouble(((Matcher)M).group(1));
if (debug) Log.v(TAG, "Number is : " + ((Matcher)M).group(1));
}
catch (Exception ex) {
n = 0.0;
}
}
return n;
}
Related
I'm trying to parse a html tag so far I got the text which can be as follows:
"Guide Price £50,000"
or
"£50,000"
or even
"£50,000 - £55,000"
In the third case to make things simpler all I need is the first price listed.
My question is how can I convert the following numbers into an int or double, preferably an int as the numbers are quite large. Would number formatter do this or would I need a regex expression especially if some text trails the tag block.
Example after what I got so far
String priceNumber = url.select("span.price").text(); //using JSoup Libary
String priceNumber = priceNumber.replaceAll("[^\\d.])
This removes everything which is not a digit I think.
What if the example has 2 numbers in it how do I get the first?
Use a regex with Matcher.find to search for occurrences, then remove the commas and try to parse. Here's the decimal case:
String input = "£50,000 - £55,000";
Pattern regex = Pattern.compile("\\d[\\d,\\.]+");
Matcher finder = regex.matcher(input);
if( finder.find() ) { // or while() if you want to process each
try {
double value = Double.parseDouble(finder.group(0).replaceAll(",", ""));
// do something with value
} catch (NumberFormatException e ) {
// handle unparseable
}
}
Youu can convert any String to a int or double with Integer.parseInt(\\String you want to convert) or Double.parseDouble(\\String you want to convert) respectively.
In your first and second case this would get you 50000.
In the third cae you need to split the string into 2 first and then repeat the trick.
Your title is a bit misleading as you are not asking on how to convert from pound to lets say euro.
Use a regex to remove the unimportant characters and then parse the result as a double. You can then truncate to int if you only care about dollar values.
NumberFormat format = NumberFormat.getInstance();
format.parse(priceNumber.replaceAll("[^\\d]*([\\d,]*).*", "$1")).doubleValue()
The first part of the replace pattern [^\\d] matches and throws away leading characters, the second part ([\\d,]) saves the next series of digits and commas, then the third part .* throws away the rest of the input.
Then the whole input is replaced with the contents of the first saved match (the second part of the replace pattern).
Then you use the NumberFormat class to parse the number (you could use Double.parseDouble() if it weren't for the comma)
This will work I think!
String string = "This is £50,000 pounds, this is £5.00 pounds.";
String newString = string;
while (string.contains("£")) {
if (string.indexOf("£") != -1) {
// it contains £
string = string.substring(string.indexOf("£"));
newString = string.substring(0, string.indexOf(" "));
string = string.replaceFirst(newString, "");
newString = newString.replaceAll("£", "");
newString = newString.replaceAll(",", "");
double money = Double.parseDouble(newString);
System.out.println(money);
}
}
you can try this out (for all the cases),
String priceNumber = "£500001 wcjnwknv122333- £55,000";
String regex = "£(\\d+,?\\d+)\\D?";
Pattern p =Pattern.compile(regex);
Matcher m = p.matcher(priceNumber);
if(m.find()){
System.out.println(m.group(1));
}
Try below regex :
((\$|£)\d+\s|(\$|£)\d+-(\$|£)\d+\s)
Firstly i don't know if it's even possible. Well, I need a code which would find if in JTextArea are two or more word close to each other with the same ending (with the same two or more last letters) and auto put comma between them. For ex. "I walked played with my dog" it should fix that sentence to: "I walked, played with my dog" it should auto put comma between walked and played because they're close to each other and two last letters are the same. Can anyone help me? Thanks very much.
Regex based solution:
String inputString = "I walked played with bobby robby my dog";
Pattern p = Pattern.compile("([a-z]{2})\\s([a-z]{0,})\\1");
Matcher m = p.matcher(inputString);
while (m.find()) {
inputString = inputString.substring(0, m.start(2) - 1) + ", " + inputString.substring(m.start(2));
m = p.matcher(inputString);
}
The pattern searches for places where there are 2 letters, a space, then some more letters, then the first 2 letters again.
I tweaked the input string to prove it was working, and my output was as expected:
'I walked played with bobby robby my dog'
becomes:
'I walked, played with bobby, robby my dog'
addition: In order to increase the number of characters matched, increase the number in {2} to the desired value. If there is one specific pair you are looking for (e.g. ed) then change [a-z]{2} to be your desired characters. e.g.
Pattern p = Pattern.compile("(ed)\\s([a-z]{0,})\\1");
This should do it:
// First read the text from the text area:
String text = textArea1.getText();
// Split the string around spaces (thats enough based on your specification above)
String[] words = text.split(" ");
String lastLetters = "";
StringBuilder result = new StringBuilder();
// Go through building up the result by looking at one word at a time
for (String str: words) {
if (!lastLetters.isEmpty() && str.endsWith(lastLetters) {
result.append(", ");
} else {
result.append(" ");
}
result.append(str);
int start = str.length()-3;
if (start < 0) {
start = 0;
}
lastLetters = str.substring(start, str.length()-1);
}
// Set the result into the other text area
textArea2.setText(result.toString());
You might need to tweak some of the parameters into the subString to get the exact range of values you need, etc.
I need to get a substring from a java string tokenizer.
My inpunt string is = Pizza-1*Nutella-20*Chicken-65*
StringTokenizer productsTokenizer = new StringTokenizer("Pizza-1*Nutella-20*Chicken-65*", "*");
do
{
try
{
int pos = productsTokenizer .nextToken().indexOf("-");
String product = productsTokenizer .nextToken().substring(0, pos+1);
String count= productsTokenizer .nextToken().substring(pos, pos+1);
System.out.println(product + " " + count);
}
catch(Exception e)
{
}
}
while(productsTokenizer .hasMoreTokens());
My output must be:
Pizza 1
Nutella 20
Chicken 65
I need the product value and the count value in separate variables to insert that values in the Data Base.
I hope you can help me.
You could use String.split() as
String[] products = "Pizza-1*Nutella-20*Chicken-65*".split("\\*");
for (String product : products) {
String[] prodNameCount = product.split("\\-");
System.out.println(prodNameCount[0] + " " + prodNameCount[1]);
}
Output
Pizza 1
Nutella 20
Chicken 65
You invoke the nextToken() method 3 times. That will get you 3 different tokens
int pos = productsTokenizer .nextToken().indexOf("-");
String product = productsTokenizer .nextToken().substring(0, pos+1);
String count= productsTokenizer .nextToken().substring(pos, pos+1);
Instead you should do something like:
String token = productsTokenizer .nextToken();
int pos = token.indexOf("-");
String product = token.substring(...);
String count= token.substring(...);
I'll let you figure out the proper indexes for the substring() method.
Also instead of using a do/while structure it is better to just use a while loop:
while(productsTokenizer .hasMoreTokens())
{
// add your code here
}
That is don't assume there is a token.
An alternative answer you may want to use if your input grows:
// find all strings that match START or '*' followed by the name (matched),
// a hyphen and then a positive number (not starting with 0)
Pattern p = Pattern.compile("(?:^|[*])(\\w+)-([1-9]\\d*)");
Matcher finder = p.matcher(products);
while (finder.find()) {
// possibly check if the new match directly follows the previous one
String product = finder.group(1);
int count = Integer.valueOf(finder.group(2));
System.out.printf("Product: %s , count %d%n", product, count);
}
Some people dislike regex, but this is a good application for them. All you need to use is "(\\w+)-(\\d{1,})\\*" as your pattern. Here's a toy example:
String template = "Pizza-1*Nutella-20*Chicken-65*";
String pattern = "(\\w+)-(\\d+)\\*";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(template);
while(m.find())
{
System.out.println(m.group(1) + " " + m.group(2));
}
To explain this a bit more, "(\\w+)-(\\d+)\\*" looks for a (\\w+), which is any set of at least 1 character from [A-Za-z0-9_], followed by a -, followed by a number \\d+, where the+ means at least one character in length, followed by a *, which must be escaped. The parentheses capture what's inside of them. There are two sets of capturing parentheses in this regex, so we reference them by group(1) and group(2) as seen in the while loop, which prints:
Pizza 1
Nutella 20
Chicken 65
I am working on a personal project and I want to take in userinput that looks like this :
1.0+2.5+3--4
and format it to something like this :
1.0 + 2.5 + 3 - -4
so far I am using the .replace("+") to .replace(" + ") and doing that for all of the operands but the problem is it makes the user input into this:
1.0 + 2.5 + 3 - - 4
Is there a way that I can make it with the negative signs. I want to do this so I could parse the numbers into doubles and add and subtract them later on.
my code for it :
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StringMan {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String check = "-a1 +a2 + a3 +-a5";
check = check.replace("--", "+");
System.out.println(check);
Pattern pattern = Pattern.compile("\\s+");
Matcher matcher = pattern.matcher(check);
boolean expr = matcher.find();
String str = matcher.replaceAll(" ");
System.out.println(str);
}
}
output is:
-a1 +a2 - a3 +-a5
-a1 +a2 - a3 +-a5
the problem is I want the output to look like this:
-a1 + a2 - a3 + -a5
In this specific case, you can handle -- by just replacing them with +:
Take input as a string from the user
Remove all white space
Replace all -- with +
Continue parsing as desired
I would recommend using regular expressions and their "group" functionality. I would actually remove all whitespace to make things easier, take it out of the equation, one less thing to deal with. And obviously I would recommend simplifying the string, replacing "--" with "+", "*+" with "*" and so on.
now you can use a regex on your cleaned up string.
Pattern firstPat = Pattern.compile("(((\\+|-)?)\\d+(.\\d+)?)");//for matching the first number, leading sign is optional
Pattern remainingPat = Pattern.compile("(\\+|-)(\\d+(.\\d+)?)");//for remaining numbers, leading sign is mandatory.
Pattern remainingPatWithExtOps = Pattern.compile("(\\*|/|\\+|-)(-?\\d+(.\\d+)?)");//for remaining numbers, accommodating multiply and divide with negative signs(positive signs should have been cleaned out)
Matcher match = firstPat.matcher(inputString);
now you can iterate through the string using the match.find() method. and then use match.group(1) to get the sign/operation, and use match.group(2) to get the number...
So...
Double firstnum;
boolean firstNumSigned = false;
if(match.find())
{
firstNum = Double.parse(match.group(0));// Parsing handles possible sign in string.
//obv check for exceptions during this and double check group num
String tmp = match.group(1);
firstNumSigned = tmp.equals("+") || tmp.equals("-");
}
else
{//no match means the input was probably invalid....
throw new IllegalArgumentException("What the heck were you thinking inputting that?!");
}
match = remainingPat.matcher(inputString);//use our other pattern for remaining numbers
if(firstNumSigned)
{
match.find();//a signed first number will cause success here, we need to ignore this since we already got the first number
}
Double tmpRemaingingNum;
String operation;
while(match.find())
{
operation = match.group(1);
tmpRemainingNum = Double.parse(match.group(2));
//Do what you want with these values now until match.find() returns false and you are done
}
PS: code is not tested, im fairly confident of the regex, but I'm not 100% sure about the grouping brackets on the first pattern.. might need to experiment
Start by replacing -- with +, which is mathematically equivalent. Or start by replacing -- with - -, which would keep - and 4 together.
Check this ,
Read both strings and integers in between operators like '*,--,-,+"
We can read both integers and characters.
public static void main(String[] args) {
// TODO Auto-generated method stub
final Pattern remainingPatWithExt=Pattern.compile("(\\p{L}\\p{M}*)[\\p{L}\\p{M}0-9^\\-.-?_+-=<>!;]*");
String check = "a1+a2+--a7+ a3 +-a5";
Matcher matcher = remainingPatWithExt.matcher(check);
while( matcher.find())
{
System.out.println(matcher.group());
//use matcher.group(0) or matcher.group(1)
}
}
output
a1
a2
a7
a3
a5
I have a string like "portal100common2055".
I would like to split this into two parts, where the second part should only contain numbers.
"portal200511sbet104" would become "portal200511sbet", "104"
Can you please help me to achieve this?
Like this:
Matcher m = Pattern.compile("^(.*?)(\\d+)$").matcher(args[0]);
if( m.find() ) {
String prefix = m.group(1);
String digits = m.group(2);
System.out.println("Prefix is \""+prefix+"\"");
System.out.println("Trailing digits are \""+digits+"\"");
} else {
System.out.println("Does not match");
}
String[] parts = input.split("(?<=\\D)(?=\\d+$)");
if (parts.length < 2) throw new IllegalArgumentException("Input does not end with numbers: " + input);
String head = parts[0];
String numericTail = parts[1];
This more elegant solution uses the look behind and look ahead features of regex.
Explanation:
(?<=\\D) means at the current point, ensure the preceding characters ends with a non-digit (a non-digit is expressed as \D)
(?=\\d+$) means t the current point, ensure that only digits are found to the end of the input (a digit is expressed as \d)
This will only the true at the desired point you want to divide the input