String Replace problem - java

What I have:
I've got a text "Hi {0}, my name is {1}."
I've got a List<String> names = Arrays.asList("Peter", "Josh");
I'm trying to fit Peter where there's a {0} and Josh where there's a {1}.
What I want:
Hi Peter, my name is Josh.
Any ideas of how could I do it?

MessageFormat class is your friend. http://download.oracle.com/javase/1.5.0/docs/api/java/text/MessageFormat.html
String aa = "Hi {0}, my name is {1}";
Object[] bb = {"Peter" , "John"};
System.out.println(MessageFormat.format(aa, bb));

Probably simplest would be to use one of the String.replaceXX ops in a loop. Eg,
String sourceString = "Hi {1}, my name is {2}."
for (i = 0; i < names.size(); i++) {
String repText = names.get(i);
sourceString = sourceString.replace("{" + (i+1) + "}", repText);
}
This is a bit inefficient, since it's bad form to repeatedly create new Strings vs using a StringBuffer or some such, but generally text replacement of this form would be a low-frequency operation, so simplicity trumps efficiency.

List<String> names = new ArrayList<String();
names.add("Peter");
names.add("Josh");
String str = "Hi {1}, my name is {2}.";
str = str.replaceFirst("{1}", names.get(0));
str = str.replaceFirst("{2}", names.get(1));

String text = "Hi {1}, my name is {2}.";
java.util.List<String> names = Arrays.asList("Peter", "Josh");
for(String s: names) text = text.replace("{" + (names.indexOf(s) + 1) + "}", s);

You would do something like this.
List<String> names = Arrays.asList("Peter", "Josh");
System.out.printf("Hi %s, my name is %s.", names.get(0), names.get(1));
and that would be it in just 2 lines of code.

List<String> names = new ArrayList<String>();
names.add("Peter");
names.add("Josh");
System.out.println("Hi " + names.get(0) + ", my name is " + names.get(1) + ".");
My apologies if I'm taking you too literally and you wanat something more generic but this will do exactly as you asked.

I'm assuming that your list will have the correct number of elements.
`String s = "Hi {1}, my name is {2}.";`
for(int x = 1;x <= names.size();x++)
{
s.replaceFirst("{" + x +"}",names.get(x - 1));
}

Related

How do I convert a multiple strings into a set of strings?

So I have following strings,
String a = "123, 541, 123"
String b = "527"
String c = "234, 876"
I would like to loop over these strings, split the string by "," and store it in a set of string so that I have such final output,
("123", "541", "527", "234", "876")
Any idea how I can achieve this?
I have tried splitting the string but that results in Set<String[]> and not sure how to proceed with this since I am very new to this.
First, you need to separate strings in "a" and "c" variable. For that you can you can you split() method. You can try code below and adapt it in a way that fits your needs.
Set<String> strings = new HashSet<>();
String a = "123, 541, 123";
String b = "527";
String c = "234, 876";
private void addToSet(String stringNumbers) {
for(String str : Arrays.asList(stringNumbers.split(","))) {
strings.add(str);
}
}
I would do it simply like that:
String a = "123, 541, 123";
String b = "527";
String c = "234, 876";
List<String> all = Arrays.asList((a + "," + b + "," + c).split(","));
Set<String> result = new HashSet<>();
for (String s : all) {
result.add(s.trim());
}
System.out.println(result); // [123, 541, 234, 876, 527]
But I would try to the change the situtation that you have 3 different strings in the first place. Input should be an Array of Strings, so you don't have to care, if it is 1 or 37238273 different strings.
But without knowing where you have these 3 strings from, why they are 3 variables, hard to advice how to actually optimize that.
Something like this:
List<String> all = Arrays.asList((a + ", " + b + ", " + c).split(", "));
A simple approach with Stream flat-mapping:
Set<String> result = Stream.of(a, b, c)
.map(s -> s.split(", "))
.flatMap(Arrays::stream)
.collect(Collectors.toSet());
try it plz.
Set<String> result = new HashSet<>();
for (String s : (a + "," + b + "," + c).split(",")) {
result.add(s.trim());
}
In Java 9:
import java.util.Set;
Set<String> result = Set.of("123", "541", "527", "234", "876");

Multiple string replacements without affecting substituted text in subsequent iterations

I've posted about letters earlier, but this is an another topic, I have a json response that contain 2 objects, from and to , from is what to change, and to is what it will be changed to .
My code is :
// for example, the EnteredText is "ab b test a b" .
EnteredString = EnteredText.getText().toString();
for (int i = 0; i < m_jArry.length(); i++) {
JSONObject jo_inside = m_jArry.getJSONObject(i);
String Original = jo_inside.getString("from");
String To = jo_inside.getString("to");
if(isMethodConvertingIn){
EnteredString = EnteredString.replace(" ","_");
EnteredString = EnteredString.replace(Original,To + " ");
} else {
EnteredString = EnteredString.replace("_"," ");
EnteredString = EnteredString.replace(To + " ", Original);
}
}
LoadingProgress.setVisibility(View.GONE);
SetResultText(EnteredString);
ShowResultCardView();
For example, the json response is :
{
"Response":[
{"from":"a","to":"bhduh"},{"from":"b","to":"eieja"},{"from":"tes","to":"neesj"}
]
}
String.replace() method won't work here, because first it will replace a to bhduh, then b to eieja, BUT here's the problem, it will convert b in bhduh to eieja, which i don't want to.
I want to perfectly convert the letters and "words" in the String according the Json, but that what i'm failing at .
New Code :
if(m_jArry.length() > 0){
HashMap<String, String> m_li;
EnteredString = EnteredText.getText().toString();
Log.i("TestAf_","Before Converting: " + EnteredString);
HashMap<String,String> replacements = new HashMap<String,String>();
for (int i = 0; i < m_jArry.length(); i++) {
JSONObject jo_inside = m_jArry.getJSONObject(i);
String Original = jo_inside.getString("from");
String To = jo_inside.getString("to");
if(isMethodConvertingIn){
//EnteredString = EnteredString.replace(" ","_");
replacements.put(Original,To);
Log.i("TestAf_","From: " + Original + " - To: " + To + " - Loop: " + i);
//EnteredString = EnteredString.replace(" ","_");
//EnteredString = EnteredString.replace(Original,To + " ");
} else {
EnteredString = EnteredString.replace("_"," ");
EnteredString = EnteredString.replace("'" + To + "'", Original);
}
}
Log.i("TestAf_","After Converting: " + replaceTokens(EnteredString,replacements));
// Replace Logic Here
// When Finish, Do :
LoadingProgress.setVisibility(View.GONE);
SetResultText(replaceTokens(EnteredString,replacements));
ShowResultCardView();
Output :
10-10 19:51:19.757 12113-12113/? I/TestAf_: Before Converting: ab a ba
10-10 19:51:19.757 12113-12113/? I/TestAf_: From: a - To: bhduh - Loop: 0
10-10 19:51:19.757 12113-12113/? I/TestAf_: From: b - To: eieja - Loop: 1
10-10 19:51:19.757 12113-12113/? I/TestAf_: From: o - To: neesj - Loop: 2
10-10 19:51:19.758 12113-12113/? I/TestAf_: After Converting: ab a ba
You question would be clearer if you gave the expected output for the function.
Assuming it is: ab b test a b >>>> bhduheieja eieja neesjt bhduh eieja
then see the following, the key point in the Javadoc being "This will not repeat"
http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/StringUtils.html#replaceEach(java.lang.String,%20java.lang.String[],%20java.lang.String[])
Replaces all occurrences of Strings within another String.
A null reference passed to this method is a no-op, or if any "search
string" or "string to replace" is null, that replace will be ignored.
This will not repeat. For repeating replaces, call the overloaded
method.
Example 1
import org.apache.commons.lang3.StringUtils;
public class StringReplacer {
public static void main(String[] args) {
String input = "ab b test a b";
String output = StringUtils.replaceEach(input, new String[] { "a", "b", "tes" },
new String[] { "bhduh", "eieja", "neesj" });
System.out.println(input + " >>>> " + output);
}
}
Example 2
import org.apache.commons.lang3.StringUtils;
public class StringReplacer {
public static void main(String[] args) {
String input = "this is a test string with foo";
String output = StringUtils.replaceEach(input, new String[] { "a", "foo" },
new String[] { "foo", "bar"});
System.out.println(input + " >>>> " + output);
}
}
Try following:
Solution 1:
Traverse the String characters one by one and move the new String to a new StringBuffer or StringBuilder, then call toString() to get the result. This will need you to implement string matching algorithm.
Solution 2 (Using Regex):
For this, you must know the domain of your string. For example, it is [a-zA-Z] then other arbitrary characters (not part of domain) can be used for intermediate step. First replace the actual characters with arbitrary one then arbitrary ones with the target. In example below, [!##] are the arbitrary characters. These can be any random \uxxxx value as well.
String input = "a-b-c";
String output = input.replaceAll("[a]", "!").replaceAll("[b]", "#").replaceAll("[c]", "#");
output = output.replaceAll("[!]", "bcd").replaceAll("[#]", "cde").replaceAll("[#]", "def");
System.out.println("input: " + input);
System.out.println("Expected: bcd-cde-def");
System.out.println("Actual: " + output);
Your issue is quite common. To sum things up :
String test = "this is a test string with foo";
System.out.println(test.replace("a", "foo").replace("foo", "bar"));
Gives : this is bar test string with bar
Expected by you : this is foo test string with bar
You can use StrSubstitutor from Apache Commons Lang
But first you will have to inject placeholders in your string :
String test = "this is a test string with foo";
Map<String, String> valuesMap = new HashMap<>();
valuesMap.put("a", "foo");
valuesMap.put("foo", "bar");
String testWithPlaceholder = test;
// Preparing the placeholders
for (String value : valuesMap.keySet())
{
testWithPlaceholder = testWithPlaceholder.replace(value, "${"+value+"}");
}
And then, use StrSubstitutor
System.out.println(StrSubstitutor.replace(testWithPlaceholder, valuesMap));
It gives : this is foo test string with bar
Here is an method which is strictly just Java. I tried not to use any Java 8 methods here.
public static String translate(final String str, List<String> from, List<String> to, int index) {
StringBuilder components = new StringBuilder();
String token, replace;
int p;
if (index < from.size()) {
token = from.get(index);
replace = to.get(index);
p = 0;
for (int i = str.indexOf(token, p); i != -1; i = str.indexOf(token, p)) {
if (i != p) {
components.append(translate(str.substring(p, i), from, to, index + 1));
}
components.append(replace);
p = i + token.length();
}
return components.append(translate(str.substring(p), from, to, index + 1)).toString();
}
return str;
}
public static String translate(final String str, List<String> from, List<String> to) {
if (null == str) {
return null;
}
return translate(str, from, to, 0);
}
Sample test program
public static void main(String []args) {
String EnteredString = "aa hjkyu batesh a";
List<String> from = new ArrayList<>(Arrays.asList("a", "b", "tes"));
List<String> to = new ArrayList<>(Arrays.asList("bhduh", "eieja", "neesj"));
System.out.println(translate(EnteredString, from, to));
}
Output:
bhduhbhduh hjkyu eiejabhduhneesjh bhduh
Explaination
The algorithm is recursive, and it simply does the following
If a pattern found in the string matches a pattern in the from list
if there is any string before that pattern, apply the algorithm to that string
replace the found pattern with the corresponding pattern in the to list
append the replacement to the new string
discard the pattern in the from list and repeat the algorithm for the rest of the string
Otherwise append the rest of the string to the new string
You could use split like:
String[] pieces = jsonResponse.split("},{");
then you just parse the from and to in each piece and apply them with replace() then put the string back together again. (and please get your capitalization of your variables/methods right - makes it very hard to read the way you have it)
Apache Commons StringUtils::replaceEach does this.
String[] froms = new String[] {"a", "b"};
String[] tos = new String[] {"b","c"};
String result = StringUtils.replaceEach("ab", froms, tos);
// result is "bc"
Why not keep it very simple (if the JSON is always in same format, EG: from the same system). Instead of replacing from with to, replace the entire markup:
replace "from":"*from*" with "from":"*to*"
Why not just change the actual "to" and "from" labels? That way, you don't run into a situation where "bhudh" becomes "eieja". Just do a string replace on "from" and "to".

Extract text from string and write to another string

I have string like this: "Welcome Vitalii Mckay "
I need to cut from this string my name and surname, it should left in new string: "Mckay, Vitalii".
But it should be good not just for my name, it should works for other names with different length, for example:
"Welcome John Smith " -> "Smith, John"
or
"Welcome Andrea J. " -> "J., Andrea".
String name = "Welcome Vitalii Mckay";
String[] parts = name.split("\\ ");
name = parts[2] + ", " + parts[1];
Based on #Vishal's answer and OP's comment on #Max's answer, I believe this will work:
String name = " Welcome Vitalii Mckay "; // with spaces in the beginning and in the end
String[] parts = name.trim().split(" "); // you don't really need the \\
name = parts[2] + ", " + parts[1];
Just make sure you trim your String input.
Could you just use a delimiter?
i.e. use a delimiter to separate the three strings, and only print out the two needed values (Surname [2]/Firstname [1])
String s = "Welcome Vitalii Mckay";
String[] split = s.split("\\s+");
System.out.println(split[2] + ", " + split[1]);
// "Welcome"
// followed by the not of space one or more times
// then a space
// followed by anything one or more times
Pattern pattern = Pattern.compile("Welcome ([^ ]+) (.+)");
Matcher matcher = pattern.matcher("Welcome Vitalii Mckay");
if (!matcher.matches()) throw new Exception();
String firstName = matcher.group(1); // groups are captured between ()
String lastName = matcher.group(2); // groups are captured between ()

adding missing double quotes in file

I have a file which contains double quotes only to String types but i need to add missing double quotes to other fields and write into a file using java.
for example
123 ,6 ,"abc#yahoo.com"
"
should be converted to
"123 ","6 ","abc#yahoo.com" "
without trimming any value just adding the missing text qualifier around the fields. I have tried by splitting based on delimiter and then wrapping around quotes but it did not work.
please share if you have solved any issue like this.
You need to use string.replaceAll method.
string.replaceAll("(^|,)(?!\")([^,]+)", "$1\"$2\"");
DEMO
There's a solution without such a complicated regular expressions: you have to split your input by , and wrap the resulting Strings:
String[] splitted = input.split(",");
for (int i = 0; i < splitted.size(); ++i) {
if (splitted[i].charAt(0) != '"') {
splitted[i] = "\"" + splitted[i] + "\"";
}
}
String output = String.join(",", Arrays.asList(splitted)); // or any other joining technic, this is from Java 8
You can easily do it by using split() method from String class and just add quote when you need it.
Basically, I would try something like this:
public static void main (String... args) {
String st = "123 ,6 ,\"abc#yahoo.com";
String[] results = st.split(",");
String result = "";
for (String s : results) {
if (!s.startsWith("\""))
s = "\"" + s + "\"";
if (!s.endsWith("\""))
s+="\"";
s+=",";
result += s;
}
System.out.println(st);
System.out.println("-------------");
System.out.println(result);
}
This keep spaces and add some missing quotes.
I tried and the below is working...
public static void test()
{
String str = "123 ,6 ,\"abc#yahoo.com \"";
String result = "",temp="";
StringTokenizer token = new StringTokenizer(str,",");
while(token.hasMoreTokens())
{
temp = token.nextToken();
if(!temp.startsWith("\""))
result += "\""+temp+"\"";
else
result += temp;
}
System.out.println(result);
}
Please check...
Try using a simple foreach and if loop to check if the value has double quotes then add quotes to the values.
for(Object obj:YourContainer){
if(!value.contains("\"")){
String s = "\"" + value + "\"";
}
}
If you are getting fields like ""Test"" with double double quotes, try using the replace function.
String s;
for(Object obj:YourContainer){
if(!value.contains("\"")){
s = "\"" + value + "\"";
}
s = s.replace("\"\"","\"");
}

how to process string in java

I want to make strings like "a b c" to "prefix_a prefix_b prefix_c"
how to do that in java?
You can use the String method: replaceAll(String regex,String replacement)
String s = "a xyz c";
s = s.replaceAll("(\\w+)", "prefix_$1");
System.out.println(s);
You may need to tweek the regexp to meet your exact requirements.
Assuming a split character of a space (" "), the String can be split using the split method, then each new String can have the prefix_ appended, then concatenated back to a String:
String[] tokens = "a b c".split(" ");
String result = "";
for (String token : tokens) {
result += ("prefix_" + token + " ");
}
System.out.println(result);
Output:
prefix_a prefix_b prefix_c
Using a StringBuilder would improve performance if necessary:
String[] tokens = "a b c".split(" ");
StringBuilder result = new StringBuilder();
for (String token : tokens) {
result.append("prefix_");
result.append(token);
result.append(" ");
}
result.deleteCharAt(result.length() - 1);
System.out.println(result.toString());
The only catch with the first sample is that there will be an extraneous space at the end of the last token.
hope I'm not mis-reading the question. Are you just looking for straight up concatenation?
String someString = "a";
String yourPrefix = "prefix_"; // or whatever
String result = yourPrefix + someString;
System.out.println(result);
would show you
prefix_a
You can use StringTokenizer to enumerate over your string, with a "space" delimiter, and in your loop you can add your prefix onto the current element in your enumeration. Bottom line: See StringTokenizer in the javadocs.
You could also do it with regex and a word boundary ("\b"), but this seems brittle.
Another possibility is using String.split to convert your string into an array of strings, and then loop over your array of "a", "b", and "c" and prefix your array elements with the prefix of your choice.
You can split a string using regular expressions and put it back together with a loop over the resulting array:
public class Test {
public static void main (String args[]) {
String s = "a b c";
String[] s2 = s.split("\\s+");
String s3 = "";
if (s2.length > 0)
s3 = "pattern_" + s2[0];
for (int i = 1; i < s2.length; i++) {
s3 = s3 + " pattern_" + s2[i];
}
System.out.println (s3);
}
}
This is C# but should easily translate to Java (but it's not a very smart solution).
String input = "a b c";
String output (" " + input).Replace(" ", "prefix_")
UPDATE
The first solution has no spaces in the output. This solution requires a place holder symbol (#) not occuring in the input.
String output = ("#" + input.Replace(" ", " #")).Replace("#", "prefix_");
It's probably more efficient to use a StringBuilder.
String input = "a b c";
String[] items = input.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
StringBuilder sb = new StringBuilder();
foreach (String item in items)
{
sb.Append("prefix_");
sb.Append(item);
sb.Append(" ");
}
sb.Length--;
String output = sb.ToString();

Categories

Resources