Regular expressions (denominator of a fraction) - java

Soo i think i already solved it, what i did:
String pattern = "(<=|>=)\\s{0,2}((+]\\s{0,2})?(\\d+\\s{0,2}[/]\\s{0,2}(\\d{2,}|[1-9])\\s{0,2}|\\d+[.]\\d{1,2}|\\d+))\\s{0,2}";
The pattern had something wrong, i have corrected it above and now it works :)
I have an inequation that may containing >= or <=, some white spaces and a number. That number might be an integer, a decimal number with 2 decimal places or a fraction and I want to retrieve the number on the 2nd member of the inequation with the "Matcher". Example:
4x1 + 6x2 <= 40/3
I've tried to construct such a pattern and I was able to find it. But then I've remembered that a fraction cannot be divided by zero so I want to check that aswell. For that I have used the following code:
String inequation = "4x1 + 6x2 <= 40/3";
String pattern = "(<=|>=)\\s{0,2}((+]\\s{0,2})?(\\d+\\s{0,2}[/]\\s{0,2}(\\d{2,}|[1-9])\\s{0,2}\\d+|\\d+[.]\\d{1,2}|\\d+))\\s{0,2}";
Pattern ptrn = Pattern.compile(pattern);
Matcher match = ptrn.matcher(inequation);
if(match.find()){
String fraction = match.group(2);
System.out.println(fraction);
} else {
System.out.println("NO MATCH");
}
But it's not working as expected. If it has at least 2 digits on the denominator it returns correctly (e.g. 40/32). But if it only has 1 digit it only returns the integer part (e.g. 40).
Anyway to solve this?
Which expression should I use?

Do you just want the number after the inequality sign? Then do:
Matcher m = Pattern.compile("[<>]=?\\s*(.+?)\\s*$").matcher(string);
String number = m.find() ? m.group(1) : null;

You could try using debuggex to build regular expressions. It shows you a nice diagram of your expression and you can test your inputs as well.
Java implementation (validates that the numerator is non-zero.):
Matcher m = Pattern.compile("[<>]=?\\s{0,2}([0-9]*(/[1-9][0-9]*)?)$").matcher("4x1 + 6x2 <= 40/3");
if (m.find()) {
System.out.println(m.group(1));
}
You need an '$' at the end of your expression, so that it tries to match the entire inequality.

Related

Extracting a substring from String with regex in Java (with condition)

I need to extract a substring from a string using regex. The tricky (for me) part is that the string may be in one of two formats:
either LLDDDDLDDDDDDD/DDD (eg. AB1000G242424/001) or just between 1 and 7 digits (eg. 242424).
The substring I need to extract would needs to be:
If string is 7 digits or longer, then extract substring consisting of 7 digits.
Else (if string is shorter than 7 digits), then extract substring consisting of 1-6 digits.
Below is one of my tries.
String regex = ("([0-9]{7}|[0-9]{0,6})");
Pattern pattern = Pattern.compile(regex);
Matcher matcher;
matcher = pattern.matcher("242424");
String extractedNr1 = "";
while (matcher.find()) {
extractedNr1 += matcher.group();
}
matcher = pattern.matcher("AB1000G242424/001");
String extractedNr2 = "";
while (matcher.find()) {
extractedNr2 += matcher.group();
}
System.out.println("ExtractedNr1 = " + extractedNr1);
System.out.println("ExtractedNr2 = " + extractedNr2);
Output:
ExtractedNr1 = 242424
ExtractedNr2 = 1000242424001
I understand the second one is a concat from all the groups, but don't understand why matches are arranged like that. Can I make a regex that will stop immidiately after finding a match (with priority for the first option, that is 7 digits)?
I thought about using some conditional statement, but apparently these are not supported in java.util.regex, and I cannot use third party library.
I can do this in java obviously, but the whole point is in using regex.
Regex is a secundary concern, the occurrences of digits must be compared by length. As in regex \d stand for digit and \D for non-digit you can use String.splitAsStream as follows:
Optional<String> digits takeDigits(String s) {
return s.splitAsStream("\\D+")
filter(w -> !w.isEmpty() && w.length() <= 7)
max(Comparator.comparingInt(String::length));
}
You can use String.replaceAll to remove the non-digit characters:
String extracted = new String("AB1000G242424/001").replaceAll("[^0-9]","");
if (extracted.length() > 7)
extracted = extracted.substring(0, 7);
Output:
1000242

I want Java Pattern.compile to recognize positive or negative integers or decimals

In Java I want to use Pattern.compile(String regexp) to find a negative or positive integer or decimal.
Ex. (1) (11) (1.1) (11.11) (-1) (-11) (-1.1) (-11.11)
I have found several answers online that tell me this is the correct regexp, but it ignores "-" sign ever single time.
Pattern pattern1 = Pattern.compile("(\\-?\\d+(\\.\\d+)?)");
Try this:
Pattern pattern1 = Pattern.compile("(-|\\+)?\\d+");
That should match both positive and negative integer numbers.
For decimals (should match either integers or decimals):
Pattern pattern2 = Pattern.compile("(-|\\+)?\\d+((\\.{1}\\d+)?)");
String regex = "(-)?\\d+([.]\\d+)?";
We allow one optional minus (-)? for negative numbers and one optional decimal point ([.]) followed by digits (\d) for decimal numbers.
String regex = "(-)?\\d+([.]\\d+)?";
Pattern pattern = Pattern.compile(regex);
String input = "-0.123";
Matcher matcher = pattern.matcher(scr);
System.out.println(matcher.matches()); //Prints true.
I just tested your pattern and it works fine. Maybe I didnt understand the question but here is the source code I used.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Play {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Pattern p = Pattern.compile("(\\-?\\d+(\\.\\d+)?)");
Matcher m = p.matcher("(1) (11) (1.1) (11.11) (-1) (-11) (-1.1) (-11.11)");
while (m.find()) {
System.out.println("Found a " + m.group());
}
}
}
And The outcome is
run:
Found a 1
Found a 11
Found a 1.1
Found a 11.11
Found a -1
Found a -11
Found a -1.1
Found a -11.11
BUILD SUCCESSFUL (total time: 0 seconds)
If you want to include the parenthesis as well then use this pattern
[(][+-]?([0-9]*[.])?[0-9]+[)]
SOLUTION: for some reason the "-" is not be recognized, so I tried the unicode version and regexp allows unicode by doing \u2212 a.k.a. (\-). This solved my issue and i have no idea why it wouldnt work before doing this.
Pattern p = Pattern.compile("(-?(\\d+(\\.?\\d+)))");
Matcher m = p.matcher(YourString);
//m.group(1);

regex pattern matcher

Not too familiar with regex, but I have a block of code that does not seem to be working as expected, I think I know why, but would be looking for a solution.
Here is the string "whereClause"
where filter_2_id = 20 and acceptable_flag is true
String whereClause = report.getWhereClause();
String[] tokens = whereClause.split("filter_1_id");
Pattern p = Pattern.compile("(\\d{3})\\d+");
Matcher m = p.matcher(tokens[0]);
List<Integer> filterList = new ArrayList<Integer>();
if (m.find()) {
do {
String local = m.group();
filterList.add(Integer.parseInt(local));
} while (m.find());
}
When I am debugging, it looks like it gets to the if (m.find()){ but then it just completely skips over it. Is it because the regex pattern (\d{3}\d+) only looks for numbers greater than 3 digits? I actually need it to scan for any set of numbers, so should i just include it as 0-9 inside?
Help/advice please
You can try the regular expression "=\\s*(\\d+)" and then modify m.group() to m.group(1). This should look for an equal sign, possibly followed by some whitespace, and then a sequence of one or more digits. Putting the digits part in parentheses creates a group, which will be group 1 (group 0 is the whole match).

Java Regex needed

I need regex that will fail only for below patterns and pass for everything else.
RXXXXXXXXXX (X are digits)
XXX.XXX.XXX.XXX (IP address)
I have basic knowledge of regex but not sure how to achieve this one.
For the first part, I know how to use regex to not start with R but how to make sure it allows any number of digits except 10 is not sure.
^[^R][0-9]{10}$ - it will do the !R thing but not sure how to pull off the not 10 digits part.
Well, simply define a regex:
Pattern p = Pattern.compile("R[0-9]{10} ((0|1|)[0-9]{1,2}|2([0-4][0-9]|5[0-5]))(\\.((0|1|)[0-9]{1,2}|2([0-4][0-9]|5[0-5]))){3}");
Matcher m = p.matcher(theStringToMatch);
if(!m.matches()) {
//do something, the test didn't pass thus ok
}
Or a jdoodle.
EDIT:
Since you actually wanted two possible patterns to filter out, chance the pattern to:
Pattern p = Pattern.compile("(R[0-9]{10})|(((0|1|)[0-9]{1,2}|2([0-4][0-9]|5[0-5]))(\\.((0|1|)[0-9]{1,2}|2([0-4][0-9]|5[0-5]))){3})");
If you want to match the entire string (so that the string should start and end with the pattern, place ^ in from and $ at the end of the pattern.
This should work:
!(string.matches("R\d{10}|(\d{3}\\.){3}\d{3}");
The \d means any digit, the brackets mean how many times it is repeated, and the \. means the period character. Parentheses indicate a grouping.
Here's a good reference on java regex with examples.
http://www.vogella.com/tutorials/JavaRegularExpressions/article.html
Regex is not meant to validate every kind of input. You could, but sometimes it is not the right approach (similar to use a wrench as a hammer: it could do it but is not meant for it).
Split the string in two parts, by the space, then validate each:
String foo = "R1234567890 255.255.255.255";
String[] stringParts = foo.split(" ");
Pattern p = Pattern.compile("^[^R][0-9]{10}$");
Matcher m = p.macher(stringParts[0]);
if (m.matches()) {
//the first part is valid
//start validating the IP
String[] ipParts = stringParts.split("\\.");
for (String ip : ipParts) {
int ipPartValue = Integer.parseInt(ip);
if (!(ipPartValue >= 0 && ipPartValue <= 255)) {
//error...
}
}
}

Regex to get first number in string with other characters

I'm new to regular expressions, and was wondering how I could get only the first number in a string like 100 2011-10-20 14:28:55. In this case, I'd want it to return 100, but the number could also be shorter or longer.
I was thinking about something like [0-9]+, but it takes every single number separately (100,2001,10,...)
Thank you.
/^[^\d]*(\d+)/
This will start at the beginning, skip any non-digits, and match the first sequence of digits it finds
EDIT:
this Regex will match the first group of numbers, but, as pointed out in other answers, parseInt is a better solution if you know the number is at the beginning of the string
Try this to match for first number in string (which can be not at the beginning of the string):
String s = "2011-10-20 525 14:28:55 10";
Pattern p = Pattern.compile("(^|\\s)([0-9]+)($|\\s)");
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println(m.group(2));
}
Just
([0-9]+) .*
If you always have the space after the first number, this will work
Assuming there's always a space between the first two numbers, then
preg_match('/^(\d+)/', $number_string, $matches);
$number = $matches[1]; // 100
But for something like this, you'd be better off using simple string operations:
$space_pos = strpos($number_string, ' ');
$number = substr($number_string, 0, $space_pos);
Regexs are computationally expensive, and should be avoided if possible.
the below code would do the trick.
Integer num = Integer.parseInt("100 2011-10-20 14:28:55");
[0-9] means the numbers 0-9 can be used the + means 1 or more times. if you use [0-9]{3} will get you 3 numbers
Try ^(?'num'[0-9]+).*$ which forces it to start at the beginning, read a number, store it to 'num' and consume the remainder without binding.
This string extension works perfectly, even when string not starts with number.
return 1234 in each case - "1234asdfwewf", "%sdfsr1234" "## # 1234"
public static string GetFirstNumber(this string source)
{
if (string.IsNullOrEmpty(source) == false)
{
// take non digits from string start
string notNumber = new string(source.TakeWhile(c => Char.IsDigit(c) == false).ToArray());
if (string.IsNullOrEmpty(notNumber) == false)
{
//replace non digit chars from string start
source = source.Replace(notNumber, string.Empty);
}
//take digits from string start
source = new string(source.TakeWhile(char.IsDigit).ToArray());
}
return source;
}
NOTE: In Java, when you define the patterns as string literals, do not forget to use double backslashes to define a regex escaping backslash (\. = "\\.").
To get the number that appears at the start or beginning of a string you may consider using
^[0-9]*\.?[0-9]+ # Float or integer, leading digit may be missing (e.g, .35)
^-?[0-9]*\.?[0-9]+ # Optional - before number (e.g. -.55, -100)
^[-+]?[0-9]*\.?[0-9]+ # Optional + or - before number (e.g. -3.5, +30)
See this regex demo.
If you want to also match numbers with scientific notation at the start of the string, use
^[0-9]*\.?[0-9]+([eE][+-]?[0-9]+)? # Just number
^-?[0-9]*\.?[0-9]+([eE][+-]?[0-9]+)? # Number with an optional -
^[-+]?[0-9]*\.?[0-9]+([eE][+-]?[0-9]+)? # Number with an optional - or +
See this regex demo.
To make sure there is no other digit on the right, add a \b word boundary, or a (?!\d)
or (?!\.?\d) negative lookahead that will fail the match if there is any digit (or . and a digit) on the right.
public static void main(String []args){
Scanner s=new Scanner(System.in);
String str=s.nextLine();
Pattern p=Pattern.compile("[0-9]+");
Matcher m=p.matcher(str);
while(m.find()){
System.out.println(m.group()+" ");
}
\d+
\d stands for any decimal while + extends it to any other decimal coming directly after, until there is a non number character like a space or letter

Categories