I am trying to write a numerify code like in Javafakers API - java

So, I need to replace '#' in a string with a random number(0-9).
Eg: String: "I am l#earning abou#t Jav#a".
I am expecting an output like "I am l1earning abou5t Jav3a".
From the below code, I am getting an output like
"I am l2earning abou2t Jav2a" where the code is generating random numbers but after reruns.
What changes have to be performed in the code to generate different random numbers in the same string?
Java
import java.util.Random;
public class numerify {
public static void main(String[] args) {
String str = " I am l#earning abo#ut Jav#a.";
String num="1234567890";
Random r= new Random();
int n=num.length();
for (int i = 0; i < str.length() - 1; i++) {
char ran= num.charAt(r.nextInt(n));
if (str.charAt(i) == '#') {
str = str.replace('#',ran);
}
}
System.out.println(str);
}
}

The method replace replaces all occurances.
Try using replaceFirst https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#replaceFirst-java.lang.String-java.lang.String-
str = str.replaceFirst('#',ran);

If the condition is only true for the first time and after that replace will replace all occurrences of #, so there is no # available to replace next time.
You need to replace only one # at a time. Use replaceFirst instead.
if (str.charAt(i) == '#') {
char ran= num.charAt(index);
str = str.replaceFirst("#",Character.toString(ran));
}

ReplaceFirst() needs to be used instead of Replace().
ReplaceFirst()method replaces the first substring of this string that matches the given regular expression with the given replacement.

Related

Replacing all characters in a string at once in a for loop

I am learning Java and I have the following method that changes a specific letter in a string:
replaceLetter("The quick brown fox jumps over the lazy dog");
public static void replaceLetter(String string){
string = string.toLowerCase();
for (int i = 0; i < string.length(); i++){
if (string.charAt(i) == 'o'){
// System.out.println("inside if " + i);
// System.out.println("Char at " + string.charAt(i));
System.out.println(string.replace(string.charAt(i), '*'));
break;
}
// System.out.println("Outside if " + i);
}
}
What I don't understand is why is changing all the letters "o" at once, and not one by one as I thought it was supposed to do. The loop loops 12 times outside the "if statement", then goes inside the statement and changes all the characters the matches the case "o". Since the condition is "string.charAt(i)", shouldn't it change one by one? Shouldn't it change the first character that matches the case then break out of the loop?
Because that is what String#replace(char, char) does.
From the Javadoc:
Returns a new string resulting from replacing all occurrences of
oldChar in this string with newChar.
If you want to only replace one character at a time, use String#replaceFirst(char, char)
To quote the javadoc for replace, it (emphasis mine):
Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence.
It sounds like you're looking for replaceFirst to replace a single occurrence of a character at a time.
You can use setCharAt of the StringBuilder, so your snippet will look like:
public static String replaceLetter(String string){
StringBuilder stringBuilder = new StringBuilder(string.toLowerCase());
for (int i = 0; i < stringBuilder.length(); i++){
if (stringBuilder.charAt(i) == 'o'){
stringBuilder.setCharAt(i, '*');
break;
}
}
return stringBuilder.toString();
}
Also, String are immutable in Java. You need to create a new string with the character replaced.
string.replace(char a, char b) replaces all the occurrences of char a in string with char b. So you may want to use string.replaceFirst instead.

How do I create a regular expression to replace a known string while keeping optional parameters intact?

I've been trying out now for a while, but don't get it right:
In Java, I am trying to create a regular expression to match and replace a (to me known) string out of a string while keeping optional parameters intact.
Example inputs:
{067e6162-3b6f-4ae2-a171-2470b63dff00}
{067e6162-3b6f-4ae2-a171-2470b63dff00,number}
{067e6162-3b6f-4ae2-a171-2470b63dff00,number,integer}
{067e6162-3b6f-4ae2-a171-2470b63dff00,choice,1#one more item|1<another {067e6162-3b6f-4ae2-a171-2470b63dff00,number,integer} items}
(Note that the last example contains a nested reference to the same input string).
The format is always enclosing the to-be-replaced string in curly brackets {...} but with an optional list of comma-separated parameter(s).
I want to replace the input string with a number, e.g. for above input strings the result should be:
{2}
{2,number}
{2,number,integer}
{2,choice,1#one more item|1<another {2,number,integer} items}
Ideally, I'd like to have a regex that is flexible enough to handle (almost) any string as pattern to be replaced, so not just UUID kind of strings as above but also something like this:
A test string with {the_known_input_value_to_be_replaced,number,integer} not replacing the_known_input_value_to_be_replaced if its not in curly brackets of course.
which should end up as e.g.:
A test string with {3,number,integer} not replacing the_known_input_value_to_be_replaced if its not in curly brackets of course.
Note that the substitution should only take place if the input string is in curly brackets.
In Java I will be able to construct the pattern at runtime, taking the to-be-replaced string into account verbosely.
I tried e.g. \{(067e6162-3b6f-4ae2-a171-2470b63dff00)(,?.*)\} (not java escaped yet) and more generic approaches like \{(+?)(,?.*)\} , but they all don't do it right.
Any advice from regex ninjas highly appreciated :)
If you the known old string always occurs right after { you can just use
String result = old_text.replace("{" + my_old_keyword, "{" + my_new_keyword);
If you really have multiple known strings inside curly brackets (and there are no escaped curly brackets to take care of), you can use the following code:
String input = "067e6162-3b6f-4ae2-a171-2470b63dff00 is outside {067e6162-3b6f-4ae2-a171-2470b63dff00,choice,067e6162-3b6f-4ae2-a171-2470b63dff00,1#one more item|1<another {067e6162-3b6f-4ae2-a171-2470b63dff00,number,067e6162-3b6f-4ae2-a171-2470b63dff00,integer} items} 067e6162-3b6f-4ae2-a171-2470b63dff00 is outside ";
String old_key = "067e6162-3b6f-4ae2-a171-2470b63dff00";
String new_key = "NEW_KEY";
List<String> chunks = replaceInBalancedSubstrings(input, '{', '}', old_key, new_key);
System.out.println(String.join("", chunks));
Result: 067e6162-3b6f-4ae2-a171-2470b63dff00 is outside {{NEW_KEY,choice,NEW_KEY,1#one more item|1<another {NEW_KEY,number,NEW_KEY,integer} items} 067e6162-3b6f-4ae2-a171-2470b63dff00 is outside
The replaceInBalancedSubstrings method will look like:
public static List<String> replaceInBalancedSubstrings(String s, Character markStart, Character markEnd, String old_key, String new_key) {
List<String> subTreeList = new ArrayList<String>();
int level = 0;
int prevStart = 0;
StringBuffer sb = new StringBuffer();
int lastOpenBracket = -1;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (level == 0) {
sb.append(c);
}
if (c == markStart) {
level++;
if (level == 1) {
lastOpenBracket = i;
if (sb.length() > 0) {
subTreeList.add(sb.toString());
sb.delete(0, sb.length());
}
}
}
else if (c == markEnd) {
if (level == 1) {
subTreeList.add(s.substring(lastOpenBracket, i+1).replace(old_key, new_key)); // String replacement here
}
level--;
}
}
if (sb.length() > 0) {
subTreeList.add(sb.toString());
}
return subTreeList;
}
See IDEONE demo
This code will deal with replacements only inside substrings inside balanced (nested) curly braces.

Split function problems with white spaces

I want to separate a string with special characters for example:
String s = ",?hello=glu()Stop/<><$#!gluglufazoperu";
I use the split function to obtain the normal characters:
hello
glu
Stop
gluglufazoperu
I have a problem, when I use the split it puts whitespace in the begining of the string array, anyone knows how to remove it?
Here is my code example:
public class Main {
public static void main(String[] args) {
String s = ",?hello=glu()Stop/<><$#!gluglufazoperu";
String f[] = s.split("[^\\w \\s]+");
int i= 0;
while(i < f.length){
System.out.println(f[i]);
i++;
}
}
}
This is the output:
(whitespace)
hello
glu
Stop
gluglufazoperu
there is a whitespace because the first split between ',' and '?' returns an empty string "".
With your while loop you print System.out.println(""), and that is an empty line.
When you only want to print the not empty strings you should replace your System.out.println with
if(!"".equals(f[i])){
System.out.println(f[i]);
}
And (beside your question) a little tip, take a look at this tutorial.
oracle for loop tutorial
Not whitespace but empty string as ",?" is a separator too. This could happen at the end too.
You might simple skip an empty string.
You might remove those from the array, which is costly, as it makes a copy.
if (f.length > 1) {
if (f[0].isEnpty()) {
f = Arrays.copyOfRange(f, 1, f.length);
}
if (f.length > 1) {
if (f[f.length - 1].isEnpty()) {
f = Arrays.copyOfRange(f, 0, f.length - 1);
}
}
}
Remarks:
String[] f = ... is more conventional in java.
\\s already captures the space, and do you really want to keep spaces?
You could simply replace the longest prefix the string matching your regular expression with the empty string before splitting:
final String regex = "[^\\w \\s]+";
String f[] = s.replaceAll("^"+regex, "")
.split(regex);

Find a specific word and replace that before the "letter" rather than after

I have an alphabet which I want to replace before any alphabet rather than the after. For example if I have a word "instant" I want to make sure that char 'a' after the 't' should be before the 't'. It should be insatnt. Wherever any of the word has an 'a' it should be replaced before but not after. Is there any possible way out of this?
You have only given one example, so I can't post a general answer. Maybe you can generalize it:
String input = "instant";
String replaced = input.replaceAll("(\\w)a", "a$1");
You can use regex to do what you want.
In the general case you want to replace <something>a by a<something> where <something> is a single character, any character.
In regex this is replacing (\\w)a by a$1, i.e. find cases where an a is preceded by something and capture that something. Then replace it with the a followed by the captured something:
public static void main(String[] args) throws Exception {
final String s = "instant";
System.out.println(s.replaceAll("(\\w)a", "a$1"));
}
Output:
insatnt
The old-school way would be something along the following:
char reference_char = 'a';
String old_string = "instant";
char[] test_array = old_string.toCharArray();
int i = 0;
for (char c : test_array) {
if (i > 0) {
if (c == reference_char) {
test_array[i] = test_array[i - 1];
test_array[i - 1] = reference_char;
}
}
++i;
}
String new_string = new String(test_array);
System.out.println(new_string);
I hope I understood your question.
All the best!

Remove a specific word from a string

I'm trying to remove a specific word from a certain string using the function replace() or replaceAll() but these remove all the occurrences of this word even if it's part of another word!
Example:
String content = "is not like is, but mistakes are common";
content = content.replace("is", "");
output: "not like , but mtakes are common"
desired output: "not like , but mistakes are common"
How can I substitute only whole words from a string?
What the heck,
String regex = "\\s*\\bis\\b\\s*";
content = content.replaceAll(regex, "");
Remember you need to use replaceAll(...) to use regular expressions, not replace(...)
\\b gives you the word boundaries
\\s* sops up any white space on either side of the word being removed (if you want to remove this too).
content = content.replaceAll("\\Wis\\W|^is\\W|\\Wis$", "");
You can try replacing " is " by " ". The is with a space before and one after, replaced by a single space.
Update:
To make it work for the first "is" in the sentence, also do another replace of "is " for "". Replacing the first is and the first space, with an empty string.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String input = s.nextLine();
char c = s.next().charAt(0);
System.out.println(removeAllOccurrencesOfChar(input, c));
}
public static String removeAllOccurrencesOfChar(String input, char c) {
String r = "";
for (int i = 0; i < input.length(); i ++) {
if (input.charAt(i) != c) r += input.charAt(i);
}
return r;
}
}

Categories