Replace everything except positive/negative numbers - java

There are many questions already answered for replacing everything positive numbers. But, I couldn't find any answer which preserves both positive and negative numbers. I want to replace everything that isn't number(positive or negative). The output should be the following eg.
0 | success. id - 1234| -> 0 1234
and
-10 | failure. id - 2345| -> -10 2345
Apparently this answers for the positive part.

You can use this regex to match positive/negative integers:
[+-]?\b\d+\b
RegEx Demo
to match positive/negative numbers including decimals:
[+-]?\b\d+(?:\.\d+)?\b
Please note that rather than using replace you would be better off using above regex in Pattern and Matcher APIs and just get your matched data.
In case you can only use replace then use:
str = str.replaceAll( "([+-]?\\b\\d+\\b)|\\S+[ \\t]*", "$1" );
Replace Demo

I used this in Kotlin to replace all non-Double characters before parsing to a Double:
val double = str.replace("[^0-9.-]".toRegex(), "").toDoubleOrNull()

Related

Generate strings larger than and lesser than

I need to test my method which is validate input Strings larger and lesser than.
I already achieved something like that:
//given
var generex = new Generex("[a-zA-Z]{3,100}");
patientDtoIn.setFirstName(generex.random());
This regex generate Strings larger than 3 and lesser than 100. Including this 2 numbers too.
Now I need the opposite. "Lesser than 3 and larger than 100" excluding those 2 numbers. Could someone help me with that?
You can use this regex:
^(?:[a-zA-Z]{1,2}|[a-zA-Z]{101,})$
Pattern explanation:
^ - match beginning of the string
(?:...) - non capturing group (used to group pattern)
[a-zA-Z]{1,2} - match pattern 1 or 2 times
| - alternation operator
[a-zA-Z]{101,} - match pattern 101 or more times
$ - match end of the string
Regex demo

minimum number in a string should be 1 regex validation?

I have a String which I need to match. Meaning it should only contains a number followed by space or just a number and minimum number should be 1 always. For ex:
3 1 2
1 p 3
6 3 2
0 3 2
First and third are valid string and all other are not.
I came up with below regex but I am not sure how can I check for minimum number in that string should be 1 always?
str.matches("(\\d|\\s)+")
Regex used from here
Just replace \\d with [1-9].
\\d is just a shorthand for the class [0-9].
This is a better regex though: ([1-9]\\s)*[1-9]$, as it takes care of double digit issues and won't allow space at the end.
Not everything can or should be solved with regular expressions.
You could use a simple expression like
str.matches("((\\d+)\\s)+")
or something alike to simply check that your input line contains only groups of digits followed by one or more spaces.
If that matches, you split along the spaces and for each group of digits you turn it into a number and validate against the valid range.
I have a gut feeling that regular expressions are actually not sufficient for the kind of validation you need.
If it should only contains a number followed by space or just a number and minimum number should be 1 and number can also be larger than 10 you might use:
^[1-9]\\d*(?: [1-9]\\d*)*$
Note that if you want to match a space only, instead of using \s which matches more you could just add a space in the pattern.
Explanation
^ Assert the start of the string
[1-9]\\d* Match a number from 1 up
(?: [1-9]\\d*)* Repeat a number from 1 up with a prepended space
$ Assert end of the string
Regex demo
Regex is part of the solution. But I don't think that regex alone can solve your problem.
This is my proposed solution:
private static boolean isValid(String str) {
Pattern pattern = Pattern.compile("[(\\d+)\\s]+");
Matcher matcher = pattern.matcher(str);
return matcher.matches() && Arrays.stream(Arrays.stream(matcher.group().split(" "))
.mapToInt(Integer::parseInt)
.toArray()).min().getAsInt() == 1;
}
Pay attention to the mathing type: matcher.matches() - to check match against the entire input. (don't use matcher.find() - because it will not reject invalid input such as "1 p 2")

Regex - how to extract integers only not float from text

Given a text:
Why should the number 12.8 be rounded to 13. It must be rather 11
What must be a regex to extract, the integer values only:
13
11
I tried this: \d+(?!\\.)
But still no luck.
You need to use lookarounds (lookbehind, lookahead) to check what happens before and after the digits you match:
a naive approach:
(?<![0-9]|[0-9]\.)[0-9]+(?!\.?[0-9])
an efficient approach:
[0-9](?<![0-9][0-9]|[0-9]\.[0-9])[0-9]*+(?!\.[0-9])
(Because this one quickly discards positions where there is not a digit)
Note: don't forget to escape the backslashes in the java string.
You can also write it like this:
\b[0-9](?<![0-9]\.[0-9])[0-9]*+(?!\.[0-9])
I solved applying two regex. The command line bellow shows how they work:
echo "Why number 12.8 be rounded to 13. It must be rather 11" | grep -Po '\b\d+\.?\d\b' | grep -Po '^\d+$'
The first regex select all numbers, including floating points. The second regex selects only integers.
In java, use "\\b\\d+\\.?\\d\\b" to select all numbers, and "^\\d+$" to select only integers.

Java regex - Replace "x^2" with "x²" but NOT "x^27" with "x²7"

I got a string of an equation where I want to replace all occurrences of the scheme "x^2" with "x²".
My code:
String equation = "x^2";
equation = equation.replace("^2", "\u00B2"); // u00b2 is unicode for '²'
System.out.println(equation);
This works for "x^2" but for example "x^25" I'm getting the string "x²5", but in such a case I want it to stay the same "x^25".
Another example:
"x^2 + 6x" -> "x² + 6x" // ... x squared
"x^28 + 6x" -> "x^28 + 6x" // ... x to the power of 28
Thank you!
EDIT:
The solution from "Mshnik" works perfectly, even with a custom character like "y^2" instead of "x^2", thanks!
Here's a regex that will match 2 in x^2, the 2 in a^2+... but not the 2 in x^20:
(?<=\w)\^2(?![0-9.])
Specifically:
(?<= <EXP>) is a positive lookbehind on <EXP>, More explanation here
\w matches any alphabetic character, upper or lower case.
\^ matches the ^ character literally
2 matches the 2 character literally
(?! <EXP>) is a negative lookahead on <EXP> More explanation here.
[0-9.] matches all numbers and decimals, like 58 and 3.14.
Thus all together it matches the 2 that is preceded by x^ and isn't followed by a digit.
With that, you can use java's Pattern class to find and rebuild a string with the new ². More on that here
Note that in order to get a backslash into a java regex, you need the literal backslash character represented by \\. Thus the final result looks like (?<=\\w)\\^2(?![0-9.]).

Regular Expression for Percentage of marks

I am trying to create a regex that matches percentage for marks
For example if we consider few percentages
1)100%
2)56.78%
3)56 78.90%
4)34.6789%
The matched percentages should be
100%
56.78%
34.6789%
I have made an expression "\\d.+[\\d]%" but it also matches for 56 78.90% which I don't want.
If anyone knows such expression please share
\\d+(?:\\.\\d+)?%
This should do it for you.
For more stringent test use,
\b(?<!\.)(?!0+(?:\.0+)?%)(?:\d|[1-9]\d|100)(?:(?<!100)\.\d+)?%
See demo.
https://regex101.com/r/zsNIrG/2
You haven't double-escaped your dot, which means it's a wildcard for any character, including whitespace.
Use something like:
┌ integer part - any 1+ number of digits
| ┌ dot and decimal part (grouped)
| |┌ double-escaped dot
| || ┌ decimal part = any 1+ number of digits
| || | ┌ 0 or 1 greedy quantifier for whole group
| || | |
"\\d+(\\.\\d+)?%"
For instance:
String[] inputs = { "100%", "56.78%", "56 78.90%", "34.6789%" };
Matcher m = null;
for (String s: inputs) {
m = p.matcher(s);
if (m.find())
System.out.printf("Found: %s%n", m.group());
}
Output
Found: 100%
Found: 56.78%
Found: 78.90%
Found: 34.6789%
Note
This still matches the 3rd input, but only the last part.
If you want the 3rd input to just not match, you can surround your pattern with input boundaries, such as ^ for start of input, and $ for end of input.
That would become: "^\\d+(\\.\\d+)?%$"
Or, you can simply invoke Matcher#matches instead of Matcher#find.
Next step
You may want to do something with the numerical value you're retrieving.
In this case, you can surround your pattern with a group ("(\\d+(\\.\\d+)?)%") and invoke either Double.parseDouble or new BigDecimal(...) on your back-reference:
Double.parseDouble(m.group(1))
new BigDecimal(m.group(1))
^((100)|(\d{1,2}(.\d*)?))%$
Check this regular expression here: https://regex101.com/r/Ou3mJI/2
You can use this regular expression. It is valid for:
0 to 100 inclusive
With and without decimal places
Below are valid values:
100% is valid
99.802% is valid
98.7% is valid
57% is valid
0% is valid
This regular expression invalidates below values:
Negative numbers
Number > 100
Number with spaces
Invalid value examples:
-1%
99.989%
101%
56 78.90%
Hope this will help!
The RegEx \\d+(\\.?\\d+)?% would work.
All credit goes to #vks for this answer, but I was looking for a regex that matched:
Positive values between 0% - 100%
No negative values
In any given string
This includes a negative lookahead (?<!-) which excludes minus numbers.
\b(?<!-)(?<!\.)(?!0+(?:\.0+)?%)(?:\d|[1-9]\d|100)(?:(?<!100)\.\d+)?%

Categories