Replace all occurrences of group - java

I want to replace all the occurrences of a group in a string.
String test = "###,##.##0.0########";
System.out.println(test);
test = test.replaceAll("\\.0(#)", "0");
System.out.println(test);
The result I am trying to obtain is ###,##.##0.000000000
Basically, I want to replace all # symbols that are trailing the .0.
I've found this about dynamic replacement but I can't really make it work.
The optimal solution will not take into account the number of hashes to be replaced (if that clears any confusion).

#(?!.*\\.0)
You can try this.Replace by 0.See demo.
https://regex101.com/r/yW3oJ9/12

You can use a simple regex to achieve your task.
#(?=#*+$)
(?=#*+$) = A positive look-ahead that checks for any # that is preceded by 0 or more # symbols before the end of string $. Edit: I am now using a possessive quantifier *+ to avoid any performance issues.
See demo
IDEONE:
String test = "###,##.##0.0###########################################";
test = test.replaceAll("#(?=#*+$)", "0");
System.out.println(test);

You can split your text on "0.0" and replace just for the second part:
String[] splited = "###,##.##0.0########".split("0.0");
String finalString = splited[0] + "0.0" + splited[1].replaceAll("#","0");

Related

How do I enter a "." 2 spaces before every "," in a Java string

I've got a string in my Java project which looks something like this
9201,92710,94500,920,1002
How can I enter a dot 2 places before the comma? So it looks like
this:
920.1,9271.0,9450.0,92.0,100.2
I had an attempt at it but I can't get the last number to get a dot.
numbers = numbers.replaceAll("([0-9],)", "\\.$1");
The result I got is
920.1,9271.0,9450.0,92.0,1002
Note: The length of the string is not always the same. It can be longer / shorter.
Check if string ends with ",". If not, append a "," to the string, run the same replaceAll, remove "," from end of String.
Split string by the "," delimiter, process each piece adding the "." where needed.
Just add a "." at numbers.length-1 to solve the issue with the last number
As your problem is not only inserting the dot before every comma, but also before end of string, you just must add this additional condition to your capturing group:
numbers = numbers.replaceAll("([0-9](,|$))", "\\.$1");
As suggested by Siguza, you could as well use a non-capturing group which is even more what a "human" would expect to be captured in the capturing group:
numbers = numbers.replaceAll("([0-9](?:,|$))", "\\.$1");
But as a non-capturing group is (although a really nice feature) not standard Regex and the overhead is not that significant here, I would recommend using the first option.
You could use word boundary:
numbers = numbers.replaceAll("(\\d)\b", ".$1");
Your solution is fine, as long as you put a comma at the end like dan said.
So instead of:
numbers = numbers.replaceAll("([0-9],)", "\\.$1");
write:
numbers = (numbers+",").replaceAll("([0-9],)", "\\.$1");
numbers = numbers.substring(0,numbers.size()-1);
You may use a positive lookahead to check for the , or end of string right after a digit and a zeroth backreference to the whole match:
String s = "9201,92710,94500,920,1002";
System.out.println(s.replaceAll("\\d(?=,|$)", ".$0"));
// => 920.1,9271.0,9450.0,92.0,100.2
See the Java demo and a regex demo.
Details:
\\d - exactly 1 digit...
(?=,|$) - that must be before a , or end of string ($).
A capturing variation (Java demo):
String s = "9201,92710,94500,920,1002";
System.out.println(s.replaceAll("(\\d)(,|$)", ".$1$2"));
You where right to go for the replaceAll method. But your regex was not matching the end of the string, the last set of numbers.
Here is my take on your problem:
public static void main(String[] args) {
String numbers = "9201,92710,94500,920,1002";
System.out.println(numbers.replaceAll("(\\d,|\\d$)", ".$1"));
}
the regex (\\d,|\\d$) matches a digit followed by a comma \d,, OR | a digit followed by the end of the string \d$.
I have tested it and found to work.
As others have suggested you could add a comma at the end, run the replace all and then remove it. But it seems as extra effort.
Example:
public static void main(String[] args) {
String numbers = "9201,92710,94500,920,1002";
//add on the comma
numbers += ",";
numbers = numbers.replaceAll("(\\d,)", "\\.$1");
//remove the comma
numbers = numbers.substring(0, numbers.length()-1);
System.out.println(numbers);
}

how can I replace substring that occurs only once while excluding substring two or more times in a row?

Is there any way that I can do the following in java ?
String s = "acdaaefacaa";
String b = s.replaceLikeMethod("a", "");
and b becomes "cdaaefcaa". Basically replace any occurrence of the first string "a" with the other one "" unless "a" appears two or more times in a row.
You can use regex to achieve this. The features you want are
Negative LookBehind (?<!foo) Match pattern unless foo occurs right before.
Negative LookAhead. (?!foo) Match pattern unless foo occurs right afterwards
You basically need to use both at the same time with the same string as the string to match and pattern. E.g.
String pattern = "(?<!foo)foo(?!foo)";
Or to easily replace with a string known at runtime like "a"
String pattern = "(?<!foo)foo(?!foo)".replace("foo", "a");
Finally, to replace just do :
String b = s.replaceAll(pattern, "");
Use this regex: ((?<!a)a(?!a)). It uses negative lookahead and lookbehind. It matches every a that is not preceded and followed by another a.
Test:
String input = "acdaaefacaa";
String output = input.replaceAll("((?<!a)a(?!a))", "");
System.out.println(output);
Outputs:
cdaaefcaa

Remove all characters before special character in android

I have to remove ## before $$ from string ##$$abxcyhshbhs##xcznbx##. I am using:
string.split("\\#");
The problem is that it also removes # after $$.
Use replace() instead.
String text = "##$$abxcyhshbhs##xcznbx##";
text = text.replace("##$$", "$$");
You can use substring method like below
string.substring(2);
If you really want to use String.split() you can do what you want by limiting the number of results by doing:
String str = "##$$abxcyhshbhs##xcznbx##";
str = str.split("##", 2)[1];
I don't know your exact issue but as has already been said, replace() or substring() is probably a better option.
If you have unknown number of # symbols before $$ and they appear not just at the beginning of the string, you can use the following replaceAll with a regex:
String re = "#+\\${2}";
String str = "##$$abxcyh###$$shbhs##xcznbx##";
System.out.println(str.replaceAll(re, "\\$\\$")); // Note escaped $ !!!
// => $$abxcyh$$shbhs##xcznbx##
// or
re = "#+(\\${2})"; // using capturing and back-references
System.out.println(str.replaceAll(re, "$1"));
See IDEONE demo.
Do not forget to assign the variable a new value when using in your code:
str = str.replaceAll("#+(\\${2})", "$1")
If your purpose is to remove ## from first occurrence of ##$$ in the string, then following code snippet will be helpful:
if(yourString.startsWith("##$$")){
yourString.replaceFirst("##$$","$$");
}
OR considering there is only single $$ in your string, following would be helpful:
String requiredString="";
String[] splitArr = yourString.split("\\$");
if ( splitArr.length > 1 ) {
requiredString = "$$" + splitArr[splitArr.length-1];
}
I have written a code snippet here. You can make changes and execute on your own.
To literally remove the first two characters, use the following:
String s = "##$$abxcyhshbhs##xcznbx##";
s.substring(2, s.length());
This doesn't do any pattern matching to look for the $$.

Matching everything after the first comma in a string

I am using java to do a regular expression match. I am using rubular to verify the match and ideone to test my code.
I got a regex from this SO solution , and it matches the group as I want it to in rubular, but my implementation in java is not matching. When it prints 'value', it is printing the value of commaSeparatedString and not matcher.group(1) I want the captured group/output of println to be "v123_gpbpvl-testpv1,v223_gpbpvl-testpv1-iso"
String commaSeparatedString = "Vtest7,v123_gpbpvl-testpv1,v223_gpbpvl-testpv1-iso";
//match everything after first comma
String myRegex = ",(.*)";
Pattern pattern = Pattern.compile(myRegex);
Matcher matcher = pattern.matcher(commaSeparatedString);
String value = "";
if (matcher.matches())
value = matcher.group(1);
else
value = commaSeparatedString;
System.out.println(value);
(edit: I left out that commaSeparatedString will not always contain 2 commas. Rather, it will always contain 0 or more commas)
If you don't have to solve it with regex, you can try this:
int size = commaSeparatedString.length();
value = commaSeparatedString.substring(commaSeparatedString.indexOf(",")+1,size);
Namely, the code above returns the substring which starts from the first comma's index.
EDIT:
Sorry, I've omitted the simpler version. Thanks to one of the commentators, you can use this single line as well:
value = commaSeparatedString.substring( commaSeparatedString.indexOf(",") );
The definition of the regex is wrong. It should be:
String myRegex = "[^,]*,(.*)";
You are yet another victim of Java's misguided regex method naming.
.matches() automatically anchors the regex at the beginning and end (which is in total contradiction with the very definition of "regex matching"). The method you are looking for is .find().
However, for such a simple problem, it is better to go with #DelShekasteh's solution.
I would do this like
String commaSeparatedString = "Vtest7,v123_gpbpvl-testpv1,v223_gpbpvl-testpv1-iso";
System.out.println(commaSeparatedString.substring(commaSeparatedString.indexOf(",")+1));
Here is another approach with limited split
String[] spl = "Vtest7,v123_gpbpvl-testpv1,v223_gpbpvl-testpv1-iso".split(",", 2);
if (spl.length == 2)
System.out.println(spl[1]);
Byt IMHO Del's answer is best for your case.
I would use replaceFirst
String commaSeparatedString = "Vtest7,v123_gpbpvl-testpv1,v223_gpbpvl-testpv1-iso";
System.out.println(commaSeparatedString.replaceFirst(".*?,", ""));
prints
v123_gpbpvl-testpv1,v223_gpbpvl-testpv1-iso
or you could use the shorter but obtuse
System.out.println(commaSeparatedString.split(",", 2)[1]);

Regular expression to match unescaped special characters only

I'm trying to come up with a regular expression that can match only characters not preceded by a special escape sequence in a string.
For instance, in the string Is ? stranded//? , I want to be able to replace the ? which hasn't been escaped with another string, so I can have this result : **Is Dave stranded?**
But for the life of me I have not been able to figure out a way. I have only come up with regular expressions that eat all the replaceable characters.
How do you construct a regular expression that matches only characters not preceded by an escape sequence?
Use a negative lookbehind, it's what they were designed to do!
(?<!//)[?]
To break it down:
(
?<! #The negative look behind. It will check that the following slashes do not exist.
// #The slashes you are trying to avoid.
)
[\?] #Your special charactor list.
Only if the // cannot be found, it will progress with the rest of the search.
I think in Java it will need to be escaped again as a string something like:
Pattern p = Pattern.compile("(?<!//)[\\?]");
Try this Java code:
str="Is ? stranded//?";
Pattern p = Pattern.compile("(?<!//)([?])");
m = p.matcher(str);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, m.group(1).replace("?", "Dave"));
}
m.appendTail(sb);
String s = sb.toString().replace("//", "");
System.out.println("Output: " + s);
OUTPUT
Output: Is Dave stranded?
I was thinking about this and have a second simplier solution, avoiding regexs. The other answers are probably better but I thought I might post it anyway.
String input = "Is ? stranded//?";
String output = input
.replace("//?", "a717efbc-84a9-46bf-b1be-8a9fb714fce8")
.replace("?", "Dave")
.replace("a717efbc-84a9-46bf-b1be-8a9fb714fce8", "?");
Just protect the "//?" by replacing it with something unique (like a guid). Then you know any remaining question marks are fair game.
Use grouping. Here's one example:
import java.util.regex.*;
class Test {
public static void main(String[] args) {
Pattern p = Pattern.compile("([^/][^/])(\\?)");
String s = "Is ? stranded//?";
Matcher m = p.matcher(s);
if (m.matches)
s = m.replaceAll("$1XXX").replace("//", "");
System.out.println(s + " -> " + s);
}
}
Output:
$ java Test
Is ? stranded//? -> Is XXX stranded?
In this example, I'm:
first replacing any non-escaped ? with "XXX",
then, removing the "//" escape sequences.
EDIT Use if (m.matches) to ensure that you handle non-matching strings properly.
This is just a quick-and-dirty example. You need to flesh it out, obviously, to make it more robust. But it gets the general idea across.
Match on a set of characters OTHER than an escape sequence, then a regex special character. You could use an inverted character class ([^/]) for the first bit. Special case an unescaped regex character at the front of the string.
String aString = "Is ? stranded//?";
String regex = "(?<!//)[^a-z^A-Z^\\s^/]";
System.out.println(aString.replaceAll(regex, "Dave"));
The part of the regular expression [^a-z^A-Z^\\s^/] matches non-alphanumeric, whitespace or non-forward slash charaters.
The (?<!//) part does a negative lookbehind - see docco here for more info
This gives the output Is Dave stranded//?
try matching:
(^|(^.)|(.[^/])|([^/].))[special characters list]
I used this one:
((?:^|[^\\])(?:\\\\)*[ESCAPABLE CHARACTERS HERE])
Demo: https://regex101.com/r/zH1zO3/4

Categories

Resources