How to replace a specific word from String in Java - java

How to replace "{{customer}}" from this string "Congrats {{customer}}, you become the potential winner of auction" with "xyz".
Thanks in advance,
Suggestion appreciated.

like this?
String string = "Congrats {{customer}}";
String newValue = string.replace("{{customer}}", "xyz");
// 'string' remains the same..but 'newValue' has the replacement.
System.out.println(newValue);

Use the replace method on the String object to do this. Since String is immutable it will return a new object instance with the replaced text. Example:
String myString = "Congrats {{customer}}";
myString = myString.replace("{{customer}}","John");
System.out.println(myString);
Output:
Congrats John
See also the String javadoc for many more useful utility methods.

That looks like a mustache template.
See https://github.com/spullara/mustache.java
Typically, in your case:
HashMap<String, Object> scopes = new HashMap<String, Object>();
scopes.put("customer", "xyz");
Writer writer = new OutputStreamWriter(System.out);
MustacheFactory mf = new DefaultMustacheFactory();
Mustache mustache = mf.compile(new StringReader("Congrats {{customer}}, you become the potential winner of auction"), "example");
mustache.execute(writer, scopes);
writer.flush();

Using resources, you can use method like this:
String customer = "Joe Doe";
String textHello;
textHello = String.format(getString(R.string.hello_customer), customer);
where hello_customer is your string resorce strings.xml.
strings.xml part should look like this:
<string name="hello_customer">Congrats %1$s, you become the potential winner of auction with \"xyz\".</string>

Related

Java/Android: Append multiple strings, skip if string is null

I have four strings I need to append.
String food = extras.getString("food");
String file = extras.getString("file");
String parcel = extras.getString("parcel");
String others = extras.getString("others");
String itemList = new StringBuilder(food).append("\n")
.append(file).append("\n")
.append(parcel).append("\n")
.append(others).toString();
This code will prints, if I choose Food and File.
Food
File
null
null
Since Parcel and Others have no values (which is null), how to make it will print like below?
Food
File
I tried to use if else but it will be too long (14 possibilities). Is there any other way to make it shorter and effective?
Java 8's streaming capabilities offer a pretty neat way of doing this:
String itemList =
Stream.of(food, file, parcel, others)
.filter(Objects::nonNull)
.collect(Collectors.joining("\n"));
EDIT:
For older versions of java, you could do something similar with a traditional for loop, although it would be clunkier:
StringBuilder sb = new StringBuilder();
for (String s : Arrays.asList(food, file, parcel, others)) {
if (s != null) {
sb.append(s).append('\n');
}
}
String itemList = sb.toString();
You can simply replace all null values
String food = "food";
String file = "file";
String parcel = null;
String others = null;
String itemList = new StringBuilder(food).append("\n").append(file).append("\n").append(parcel).append("\n").append(others).toString();
itemList=itemList.replaceAll("\n?null\n?", "");
System.out.println(itemList);
Output :
food
file
\n?null\n? \n? mean there can be one or no \n value on both side of null
so it will simply replace all values with empty string
If you want to go for below Java 8 then its possible through Ternary Operator in java. Please see below code snippet:
String itemList = new StringBuilder(food!=null?food+"\n":"")
.append(file!=null?file+"\n":"")
.append(parcel!=null?parcel+"\n":"")
.append(others!=null?others+"\n":"")
.toString();
The itemList will have the desired result.
Hope it helps.

JSONObject is not created correctely

I create JsonObject and JsonArray as following:
JSONObject jObj = new JSONObject();
jObj.put("path", "dfds/g");
jObj.put("etag", "dfdsfsd");
jObj.put("size_bytes", 123);
JSONArray list = new JSONArray();
list.add(jObj);
String s = list.toJSONString();
The result I get:
[{"size_bytes":123,"etag":"dfdsfsd","path":"dfds\/g"}]
I expect the path component to be "path":"dfds\g", not dfds\/g
I need the field to be in order as I they in the code, but they are not as I expected:path, etag, size_bytes
I`ll be glad to get an advices how to solve the above issues
The Json encoder is escaping your forward slash which is why you're getting \/. This is completely legal syntax and not something to worry about.
You shouldn't need to worry about ordering inside a Json string, fields are inherently not ordered and relying on this could well lead to issues for you in the future.
If you absolutely MUST remove the forward slash from your string then you can do this:
s = s.replace("\\/", "/");
See String replace a Backslash for more information.
I recommend not doing this in this circumstance. Instead you should parse the String using one of the many JSON parsing libraries.
Here is an example of this in action with your sample String:
public static void main(String[] args){
String s = "[{\"size_bytes\":123,\"etag\":\"dfdsfsd\",\"path\":\"dfds\\/g\"}]";
System.out.println(s);
s = s.replace("\\/", "/");
System.out.println(s);
}
Output:
[{"size_bytes":123,"etag":"dfdsfsd","path":"dfds\/g"}]
[{"size_bytes":123,"etag":"dfdsfsd","path":"dfds/g"}]

Remove quotes from json array

I have the following problem:
I have an ArrayList in Java.
I convert the ArrayList to string like this:
Gson gson = new Gson();
String feeds += gson.toJson(arrayList);
This is the result:
[{"status":"ERROR","position":"[48.2748206,8.849529799999999]"}]
But i need the following output:
[{"status":"ERROR","position": [48.2748206,8.849529799999999]}]
The Value of position should be without quotes. How can i realize that?
Many thanks in advance
Greets
Replace the double quotes around position's value using String#replaceAll() method. Just create a regex and replace double quotes with empty sting.
Try with Positive Lookbehind and Positive Lookahead.
sample code:
String json = "[{\"status\":\"ERROR\",\"position\":\"[48.2748206,8.849529799999999]\"}]";
String regex = "(?<=\"position\":)\"|\"(?=\\}\\])";
System.out.println(json.replaceAll(regex, ""));
Here is DEMO
Try with grouping and substitutions as well.
sample code:
String json = "[{\"status\":\"ERROR\",\"position\":\"[48.2748206,8.849529799999999]\"}]";
String regex = "(\"position\":)\"([^\"]*)\"";
System.out.println(json.replaceAll(regex, "$1$2"));
Here is DEMO
I don't think you should go like this, may be you should change your work structure, But if you do want to typecast manually, then you can do it this way.
Suppose you have a JSONArray object like this:
JSONArray arr=[{"status":"ERROR","position":"[48.2748206,8.849529799999999]"}];
Then you can take out JSONObject like this:
Iterator iterator = array.iterator();
while(iterator.hasNext()){
Gson gson = new Gson();
ClassToCastInto obj = gson.fromJson((JsonElement)iterator.next();, ClassToCastInto.class);
System.out.println(obj.someProperty);
}
Consider using a Gson JsonWriter:
StringWriter buffer = new StringWriter();
JsonWriter writer = new JsonWriter(buffer);
writer.beginArray().beginObject();
writer.name("status").value("ERROR");
writer.name("position").beginArray();
for (double value : Arrays.asList(48.2748206, 8.849529799999999)) {
writer.value(value);
}
writer.endArray().endObject().endArray().close();
String json = buffer.toString();

Create nested JSON with minimal-json?

I'm using minimal-json (github) and am trying to create a nested JSON like so:
String jsonInner = new JsonObject().add("Inner", "i").toString();
String jsonMiddle = new JsonObject().add("Middle", jsonInner).toString();
String jsonOuter = new JsonObject().add("Outer", jsonMiddle).toString();
In my debug console, the result looks like this:
{"Outer":"{\"Middle\":\"{\\\"Inner\\\":\\\"i\\\"}\"}"}
Not quite what I was expecting; there is a bit much escaping going on...
I'm a bit slow today; can anyone please point out how to do this properly?
What about:
JsonValue inner = new JsonObject().add("Inner", "i");
JsonValue middle = new JsonObject().add("Middle", inner);
String outerAsString = new JsonObjec().add("Outer", middle).toString();
?
The problem is that you add a serialized JSON as a String in middle and outer; this is not what you want.

Is there a way to render a string like 'Hello, %(name)s' % {'name':'Felix'} in Java?

In Python we can do this easily:
data = {'name':'Felix'}
s = 'Hello, %(name)s' % data
s
'Hello, Felix'
Is there a similar way in Java to implement the same thing?
PS:
Sorry for the unclear question. the use case is : we have a map which stores the key-values, the Template only need to specify a key in the map, then the value of the key will be in the place where the key is in the template.
AFAIK you can use String#format for this:
String name = "Felix";
String s = String.format("Hello, %s", name);
System.out.println(s);
This will print
Hello, Felix
More info about how to use the formatting of String#format can be found on java.util.Formatter syntax
You want String.format method.
String data = "Hello, %s";
String updated = String.format(data, "Felix");
If you want to replace only Strings with Strings then code from second part of my answer will be better
Java Formatter class doesn't support %(key)s form, but instead you can use %index$s where index is counted from 1 like in this example
System.out.format("%3$s, %2$s, %1s", "a", "b", "c");
// indexes 1 2 3
output:
c, b, a
So all you need to do is create some array that will contain values used in pattern and change key names to its corresponding indexes (increased by 1 since first index used by Formatter is written as 1$ not as 0$ like we would expect for arrays indexes).
Here is example of method that will do it for you
// I made this Pattern static and put it outside of method to compile it only once,
// also it will match every (xxx) that has % before it, but wont include %
static Pattern formatPattern = Pattern.compile("(?<=%)\\(([^)]+)\\)");
public static String format(String pattern, Map<String, ?> map) {
StringBuffer sb = new StringBuffer();
List<Object> valuesList = new ArrayList<>();
Matcher m = formatPattern.matcher(pattern);
while (m.find()) {
String key = m.group(1);//group 1 contains part inside parenthesis
Object value = map.get(key);
// If map doesn't contain key, value will be null.
// If you want to react somehow to null value like throw some
// Exception
// now is the good time.
if (valuesList.contains(value)) {
m.appendReplacement(sb, (valuesList.indexOf(value) + 1) + "\\$");
} else {
valuesList.add(value);
m.appendReplacement(sb, valuesList.size() + "\\$");
}
}
m.appendTail(sb);
return String.format(sb.toString(), valuesList.toArray());
}
usage
Map<String, Object> map = new HashMap<>();
map.put("name", "Felix");
map.put("age", 70);
String myPattern =
"Hi %(emptyKey)s! My name is %(name)s %(name)s and I am %(age)s years old";
System.out.println(format(myPattern, map));
output:
Hi null! My name is Felix Felix and I am 70 years old
As you can see you can use same key few times (in our case name) and if your map wont contain key used in your String pattern (like emptyKey) it will be replaced with null.
Above version was meant to let you set type of data like s d and so on, but if your data will always be replaced with Strings, then you can skip String.format(sb.toString(), valuesList.toArray()) and replace all your keys with values earlier.
Here is simpler version that will accept only map with <String,String> key-value relationship.
static Pattern stringsPattern = Pattern.compile("%\\(([^)]+)\\)s\\b");
public static String formatStrings(String pattern, Map<String, String> map) {
StringBuffer sb = new StringBuffer();
Matcher m = stringsPattern.matcher(pattern);
while (m.find()) {
// we can't use null as replacement so we need to convert it to String
// first. We can do it with String.valueOf method
m.appendReplacement(sb, String.valueOf(map.get(m.group(1))));
}
m.appendTail(sb);
return sb.toString();
}
Under this use case, you need a template engine like velocity or freemarker to use a Map-like data structure to render a string template, there is no builtin module in java to do that. like this(with velocity):
public static void main(String[] args) {
Context context = new VelocityContext();
context.put("appid", "9876543d1");
context.put("ds", "2013-09-11");
StringWriter sw = new StringWriter();
String template = "APPID is ${appid} and DS is ${ds}";
Velocity.evaluate(context, sw, "velocity", template);
System.out.println(sw.toString());
}
If you want more advanced techniques like i18n support, you can use the advanced Message Format features
ex:
in langage properties files you add the property 'template' wich is your message
template = At {2,time,short} on {2,date,long}, \
we detected {1,number,integer} spaceships on \
the planet {0}.
then you can format your valriables pass the arguments in an array:
Object[] messageArguments = {
"Mars",
new Integer(7),
new Date()
};
You call the formatter it this way:
MessageFormat formatter = new MessageFormat("");
formatter.setLocale(currentLocale);
formatter.applyPattern(messages.getString("template"));
String output = formatter.format(messageArguments);
the detailed example is here
http://docs.oracle.com/javase/tutorial/i18n/format/messageFormat.html

Categories

Resources