I have comma separated string variable like:
String doctors = "doc_vijayan,doc_zubair,doc_Raja"
But i want to delete "doc_" from the above String and First Letter should display in capital. I need output like this:
String doctors1 = "Vijayan, Zubair, Raja"
How to do that?
You can try that :
public String splitDoctors(String doctorsString){
String[] doctors = doctorsString.split(",");
boolean isFirst = true;
StringBuilder sb = new StringBuilder();
for(String doctor : doctors){
if(!isFirst){
sb.append(", ");
}else{
isFirst = false;
}
sb.append(doctor.substring(4,5).toUpperCase());
sb.append(doctor.substring(5));
}
return sb.toString();
}
Guava
With Guava, you can write something like this:
import com.google.common.base.*;
import com.google.common.collect.*;
//...
String doctors = "doc_vijayan,doc_zubair,doc_Raja";
Function<String,String> chopAndCap =
new Function<String,String>() {
#Override public String apply(String from) {
return from.substring(4, 5).toUpperCase()
+ from.substring(5);
}
};
Iterable<String> docs = Splitter.on(',').split(doctors);
docs = Iterables.transform(docs, chopAndCap);
doctors = Joiner.on(", ").join(docs);
System.out.println(doctors);
// Vijayan, Zubair, Raja
So the concrete logical steps are:
Define a Function to perform the chop-and-cap
Use Splitter to split into Iterable<String>
Iterables.transform each element using the above Function
Use Joiner to join from the transformed Iterable back to a String
If you're comfortable with this kind of programming style, you can just assemble the entire process into one smooth operation:
System.out.println(
Joiner.on(", ").join(
Iterables.transform(
Splitter.on(',').split(doctors),
new Function<String,String>() {
#Override public String apply(String from) {
return from.substring(4, 5).toUpperCase()
+ from.substring(5);
}
}
)
)
);
// Vijayan, Zubair, Raja
Apache Commons Lang
With Apache Commons Lang, you can write something like this:
import org.apache.commons.lang.*;
//...
String doctors = "doc_vijayan,doc_zubair,doc_Raja";
String[] docs = StringUtils.split(doctors, ',');
for (int i = 0; i < docs.length; i++) {
docs[i] = StringUtils.capitalize(
StringUtils.substringAfter(docs[i], "doc_")
);
}
doctors = StringUtils.join(docs, ", ");
System.out.println(doctors);
// Vijayan, Zubair, Raja
Note that you if you have both Guava and Apache Commons Lang, you can use StringUtils.capitalize/substringAfter in chopAndCap function above.
final String[] docs = doctors.split(",");
final StringBuilder sb = new StringBuilder();
for (final String d : docs) {
String doct = d.replace("doc_", "");
doct = doct.subString(0,1).toUpperCase() + doct.subString(1).toLowerCase();
sb.append(sb.length() > 0 ? ", " : "");
sb.append(doct);
} // you should be able to do the rest.
String regex = "doc_.";
Matcher matcher = Pattern.compile(regex).matcher(doctors);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String group = matcher.group();
int i = group.length() - 1;
matcher.appendReplacement(sb, String.valueOf(group.charAt(i)).toUpperCase());
}
matcher.appendTail(sb);
System.out.print(sb.toString());
The easiest way is to use 'any' StringUtils library out there. For example org.apache.commons.lang.StringUtils has a chomp and a capitalize method which should bring you a long way.
Related
I want to replace all occurrences of particular string with different UUID's. For example,
content = content.replaceAll("xyz", "xyz" + generateUUID());
but problem here is that all the "xyz"'s will get replaced by same UUID. But I want that each "xyz" gets replaced by an individual unique ID. How can this be done?
You can do this using Matcher.appendReplacement. This will give you the replaceAll functionality of a complete regex (not just a static String). Here, I use uidCounter as a very simple generateUUID; you should be able to adapt this to your own generateUUID function.
public class AppendReplacementExample {
public static void main(String[] args) throws Exception {
int uidCounter = 1000;
Pattern p = Pattern.compile("xyz");
String test = "abc xyz def xyz ghi xyz";
Matcher m = p.matcher(test);
StringBuffer sb = new StringBuffer();
while(m.find()) {
m.appendReplacement(sb, m.group() + uidCounter);
uidCounter++;
}
m.appendTail(sb);
System.out.println(sb.toString());
}
}
Output:
abc xyz1000 def xyz1001 ghi xyz1002
You could use a StringBuilder (for efficiency, since String is immutable), a while loop and something like
// content = content.replaceAll("xyz", "xyz" + generateUUID());
StringBuilder sb = new StringBuilder(content);
String toReplace = "xyz";
int toReplaceLen = toReplace.length();
int pos;
while ((pos = sb.indexOf(toReplace)) > -1) {
sb.replace(pos, pos + toReplaceLen, generateUUID());
}
// content = sb.toString(); // <-- if you want to use content.
It looks like you'd like a way to say something like this:
content = content.replaceAll("xyz", x -> x + generateUUID());
Here's an adaptation of durron597's answer that lets you do almost that:
content = replaceAll(content, "xyz", x -> x + generateUUID());
public static String replaceAll(String source, String regex,
Function<String, String> replacement) {
StringBuffer sb = new StringBuffer();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(source);
while (matcher.find()) {
matcher.appendReplacement(sb, replacement.apply(matcher.group(0)));
}
matcher.appendTail(sb);
return sb.toString();
}
I have string with value as ||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||
I am trying to write code which should remove duplicates and return the unique values retaining the demiliters like this ||HelpDesk||IT Staff||Admin||Audit||
My code is using HashSet to remove duplicates but the problem is it is removing delimiters. How can I retain delimiters by removing duplicate values only.
Below is my code after removing duplicates and adding back delimiters. But not sure if there is easy way of doing this.
public static void main(String[] args) {
TestDuplicates testDuplicates = new TestDuplicates();
String bRole = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
List<String> listWithoutDuplicates = new ArrayList<String>();
String noDup = "";
List<String> splittedStringList =
new ArrayList<String>();
SplitOperations splitOperations =
new SplitOperations();
splittedStringList =
splitOperations.splitString(bRole);
for (int i = 0; i < splittedStringList.size(); i++) {
HashSet<String> listToSet = new HashSet<String>(splittedStringList);
listWithoutDuplicates = new ArrayList<String>(listToSet);
}
for(int i=0;i<listWithoutDuplicates.size();i++){
noDup = noDup + "||"+listWithoutDuplicates.get(i);
System.out.println(listWithoutDuplicates.get(i));
}
System.out.println("No Duplicate is::"+ noDup+"||");
}
Thanks
You could use a LinkedHashSet to preserve insertion order. Once you splitted the String by "||" just add the delimiters when constructing back the String.
String s = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
Set<String> set = new LinkedHashSet<>(Arrays.asList(s.split(Pattern.quote("||"))));
String noDup = "||";
for(String st : set) {
if(st.isEmpty()) continue;
noDup += st+"||";
}
Or using the new java 8 Stream API :
String noDup = "||"+
Arrays.stream(s.split(Pattern.quote("||")))
.distinct()
.filter(st -> !st.isEmpty()) //we need to remove the empty String produced by the split
.collect(Collectors.joining("||"))+"||";
Both approaches yield the same result (||HelpDesk||IT Staff||Admin||Audit||).
public String removeDublicate () {
String str = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
String split[] = str.split("\\|\\|");
String newStr = "";
for (String s : split) {
if (!s.isEmpty() && !newStr.contains(s)) {
newStr += "||" + s;
}
}
newStr += "||";
return newStr;
}
Something like that? str could be an argument.
Edit #1
If you want to get rid of && !newStr.contains(s) you can use a HashSet<String> instead. I think that is overkill however. .contains(s) will do the trick when the string is small such as this.
This should work, also it will maintain sequence of elements if you want. Note that I have not written code to put delimiters again.
public static void main(String s[]){
String a = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
a = a.replaceAll("\\|\\|",",");
String arr[] = a.split(",");
//linked hash set in case you want to maintain the sequence of elements
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr));
set.remove("");
System.out.println(set);
//Iterate through the set and put your delimiters here again
}
Using Guava lib it's a one liner:
Joiner.on("||").skipNulls(Splitter.on("||").trimResults().split(<target_string>);)
Here is my attempt at it:
import java.util.*;
public class Seperator {
public static void main(String[] args) {
String bRole = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
List<String> listWithoutDuplicates = new ArrayList<String>();
String noDup = "";
List<String> splittedStringList = new ArrayList<String>();
splittedStringList = Arrays.asList(bRole.split("\\|\\|"));
LinkedHashSet<String> listToSet = new LinkedHashSet<String>(splittedStringList);
noDup = Seperator.join(listToSet, "||");
System.out.println("No Duplicate is::"+ noDup+"||");
}
public static String join(Set<String> set, String sep) {
String result = null;
if(set != null) {
StringBuilder sb = new StringBuilder();
Iterator<String> it = set.iterator();
if(it.hasNext()) {
sb.append(it.next());
}
while(it.hasNext()) {
sb.append(sep).append(it.next());
}
result = sb.toString();
}
return result;
}
}
LinkedHashSet are mainly used to preserve the order and ofcourse get uniques elements. Joining is pretty standard, but we can use Google's Guava Library also (Joiner):
So, instead of Seperator.join(listToSet, "||");
You'll have: Joiner.on("||").join(listToSet);
Here's a regex-based one liner:
str = str.replaceAll("(\\|[^|]+)(?=.*\\1\\|)", "");
This works by replacing every term that is followed by itself somewhere ahead via a look ahead assertion that uses a back reference.
Here's a non-regex java 8 one liner:
Arrays.stream(str.substring(1).split("[|]")).distinct().collect(Collectors.joining("|", "|", "|"));
I want to remove the following words from end of String ‘PTE’, ‘LTD’, ‘PRIVATE’ and ‘LIMITED’
i tried the code but then i stuck. i tried this
String[] str = {"PTE", "LTD", "PRIVATE", "LIMITED"};
String company = "Basit LTD";
for(int i=0;i<str.length;i++) {
if (company.endsWith(str[i])) {
int position = company.lastIndexOf(str[i]);
company = company.substring(0, position);
}
}
System.out.println(company.replaceAll("\\s",""));
It worked. But suppose the company is Basit LIMITED PRIVATE LTD PTE or Basit LIMITED PRIVATE PTE LTD or any combination of four words in the end. Then the above code just remove the last name i.e., PTE or PRIVATE and so on, and the output is BasitLIMITEDPRIVATELTD.
I want output to be just Basit
How can i do it?
Thanks
---------------Edit---
Please note here the company name is just an example, it is not necessary that it is always the same. may be i have name like
String company = "Masood LIMITED LTD PTE PRIVATE"
or any name that can have the above mentioned words at the end.
Thanks
You can do this in single line. no need to loop through. just use String#replaceAll(regex, str).
company = company.replaceAll("PTE$*?|LTD$*?|PRIVATE$*?|LIMITED$*?","");
If you place the unwanted words in the map it will be ommitted in the resultant string
HashMap map = new HashMap();
map.put("PTE", "");
map.put("LTD", "");
map.put("PRIVATE", "");
map.put("LIMITED", "");
String company = "Basit LTD PRIVATE PTE";
String words[] = company.split(" ");
String resultantStr = "";
for(int k = 0; k < words.length; k++){
if(map.get(words[k]) == null) {
resultantStr += words[k] + " ";
}
}
resultantStr = resultantStr.trim();
System.out.println(" Trimmed String: "+ resultantStr);
If you want to remove these suffixes only at the end of the string, then you could introduce a while loop:
String[] str = {"PTE", "LTD", "PRIVATE", "LIMITED"};
boolean foundSuffix = true;
String company = "Basit LTD";
while (foundSuffix) {
foundSuffix = false;
for(int i=0;i<str.length;i++) {
if (company.endsWith(str[i])) {
foundSuffix = true;
int position = company.lastIndexOf(str[i]);
company = company.substring(0, position);
}
}
}
System.out.println(company.replaceAll("\\s",""));
If you don't mind transforming PTE Basit LIMITED INC to Basit (and also remove the first PTE), then replaceAll should work, as explained by others.
I was trying to do exactly same thing for one of my projects. I wrote this code few days earlier. Now I was exactly trying to find a much better way to do it, that's how I found this Question. But after seeing other answers I decided to share my version of the code.
Collection<String> stopWordSet = Arrays.asList("PTE", "LTD", "PRIVATE", "LIMITED");
String company = "Basit LTD"; //Or Anything
String[] tokens = company.split("[\#\]\\\_\^\[\"\#\ \!\&\'\`\$\%\*\+\(\)\.\/\,\-\;\~\:\}\|\{\?\>\=\<]+");
Stack<String> tokenStack = new Stack<>();
tokenStack.addAll(Arrays.asList(tokens));
while (!tokenStack.isEmpty()) {
String token = tokenStack.peek();
if (stopWordSet.contains(token))
tokenStack.pop();
else
break;
}
String formattedCompanyName = StringUtils.join(tokenStack.toArray());
Try this :
public static void main(String a[]) {
String[] str = {"PTE", "LTD", "PRIVATE", "LIMITED"};
String company = "Basit LIMITED PRIVATE LTD PTE";
for(int i=0;i<str.length;i++) {
company = company.replaceAll(str[i], "");
}
System.out.println(company.replaceAll("\\s",""));
}
All you need is to use trim() and call your function recursively, Or each time you remove a sub string from the end, reset your i to 0.
public class StringMatchRemove {
public static void main(String[] args) {
String str="my name is noorus khan";
String search="noorus";
String newString="";
String word=str.replace(search," ");
StringTokenizer st = new StringTokenizer(word," ");
while(st.hasMoreTokens())
{
newString = newString + st.nextToken() + " ";
}
System.out.println(newString);
}
first using the replace method we get word=my name is ..... khan (Note: here(.) represents the space). Now we should have to remove these spaces for that we are creating a new string adding all the token simply.
Output: my name is khan
I often use this piece of code in PHP
$ordine['address'] = implode(', ', array_filter(array($cliente['cap'], $cliente['citta'], $cliente['provincia'])));
It clears empty strings and join them with a ",". If only one remains it doesn't add an extra unneeded comma. It doesn't add a comma at the end. If none remains it returns empty string.
Thus I can get one of the following results
""
"Street abc 14"
"Street abc 14, 00168"
"Street abc 14, 00168, Rome"
What is the best Java implementation (less code) in Java without having to add external libraries (designing for Android)?
Updated version using Java 8 (original at the end of post)
If you don't need to filter any elements you can use
String.join(CharSequence delimiter, CharSequence... elements)
String.join(" > ", new String[]{"foo", "bar"});
String.join(" > ", "foo", "bar");
or String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
String.join(" > ", Arrays.asList("foo", "bar"));
Since Java 8 we can use StringJoiner (instead of originally used StringBulder) and simplify our code.
Also to avoid recompiling " *" regex in each call of matches(" *") we can create separate Pattern which will hold its compiled version in some field and use it when needed.
private static final Pattern SPACES_OR_EMPTY = Pattern.compile(" *");
public static String implode(String separator, String... data) {
StringJoiner sb = new StringJoiner(separator);
for (String token : data) {
if (!SPACES_OR_EMPTY.matcher(token).matches()) {
sb.add(token);
}
}
return sb.toString();
}
With streams our code can look like.
private static final Predicate<String> IS_NOT_SPACES_ONLY =
Pattern.compile("^\\s*$").asPredicate().negate();
public static String implode(String delimiter, String... data) {
return Arrays.stream(data)
.filter(IS_NOT_SPACES_ONLY)
.collect(Collectors.joining(delimiter));
}
If we use streams we can filter elements which Predicate. In this case we want predicate to accept strings which are not only spaces - in other words string must contain non-whitespace character.
We can create such Predicate from Pattern. Predicate created this way will accept any strings which will contain substring which could be matched by regex (so if regex will look for "\\S" predicate will accept strings like "foo ", " foo bar ", "whatever", but will not accept " " nor " ").
So we can use
Pattern.compile("\\S").asPredicate();
or possibly little more descriptive, negation of strings which are only spaces, or empty
Pattern.compile("^\\s*$").asPredicate().negate();
Next when filter will remove all empty, or containing only spaces Strings we can collect rest of elements. Thanks to Collectors.joining we can decide which delimiter to use.
Original answer (before Java 8)
public static String implode(String separator, String... data) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.length - 1; i++) {
//data.length - 1 => to not add separator at the end
if (!data[i].matches(" *")) {//empty string are ""; " "; " "; and so on
sb.append(data[i]);
sb.append(separator);
}
}
sb.append(data[data.length - 1].trim());
return sb.toString();
}
You can use it like
System.out.println(implode(", ", "ab", " ", "abs"));
or
System.out.println(implode(", ", new String[] { "ab", " ", "abs" }));
Output ab, abs
Why so serious?
Try StringUtils.join(new String[] {"Hello", "World", "!"}, ", ") !
Here is an Android-specific answer that may be helpful to some:
String combined = TextUtils.join(",", new String[]{"Red", "Green", "Blue"});
// Result => Red,Green,Blue
Be sure to import the TextUtils class:
import android.text.TextUtils;
You'd have to add your strings to an ArrayList, remove empty ones, and format it accordingly:
public static String createAddressString( String street, String zip_code, String country) {
List<String> list = new ArrayList<String>();
list.add( street);
list.add( zip_code);
list.add( country);
// Remove all empty values
list.removeAll(Arrays.asList("", null));
// If this list is empty, it only contained blank values
if( list.isEmpty()) {
return "";
}
// Format the ArrayList as a string, similar to implode
StringBuilder builder = new StringBuilder();
builder.append( list.remove(0));
for( String s : list) {
builder.append( ", ");
builder.append( s);
}
return builder.toString();
}
Additionally, if you had String[], an array of strings, you can easily add them to an ArrayList:
String[] s;
List<String> list = new ArrayList<String>( Arrays.asList( s));
Using Streams (for Java 8 and later) would be an alternate possible solution for this.
You are required to import
java.util.stream.Collectors;
to use the join process
You may use:
Arrays.asList("foo","bar").stream().collect(Collectors.joining(","));
to achieve the desired result.
A simple Implode
public static String implode(String glue, String[] strArray)
{
String ret = "";
for(int i=0;i<strArray.length;i++)
{
ret += (i == strArray.length - 1) ? strArray[i] : strArray[i] + glue;
}
return ret;
}
You can create overloads for it..
The above it equivalent of php implode.
Here is what you want:
import java.lang.*
public static String customImplode(String glue, String[] strArray)
{
String ret = "";
for(int i=0;i<strArray.length;i++)
{
if (strArray[i].trim() != "")
ret += (i == strArray.length - 1) ? strArray[i] : strArray[i] + glue;
}
return ret;
}
Here's my implode implementation:
/**
* Implodes the specified items, gluing them using the specified glue replacing nulls with the specified
* null placeholder.
* #param glue The text to use between the specified items.
* #param nullPlaceholder The placeholder to use for items that are <code>null</code> value.
* #param items The items to implode.
* #return A <code>String</code> containing the items in their order, separated by the specified glue.
*/
public static final String implode(String glue, String nullPlaceholder, String ... items) {
StringBuilder sb = new StringBuilder();
for (String item : items) {
if (item != null) {
sb.append(item);
} else {
sb.append(nullPlaceholder);
}
sb.append(glue);
}
return sb.delete(sb.length() - glue.length(), sb.length()).toString();
}
public static String implode(List<String> items, String separator) {
if (items == null || items.isEmpty()) {
return null;
}
String delimiter = "";
StringBuilder builder = new StringBuilder();
for (String item : items) {
builder.append(delimiter).append(item);
delimiter = separator;
}
return builder.toString();
}
Use this simple function:
private String my_implode(String spacer, String[] in_array){
String res = "";
for (int i = 0 ; i < in_array.length ; i++) {
if (!res.equals("")) {
res += spacer;
}
res += in_array[i];
}
return res;
}
Use:
data_arr = {"d1", "d2", "d3"};
your_imploded_text = my_implode(",", data_arr);
// Output: your_imploded_text = "d1,d2,d3"
I want to insert a % character before after every letter in a string, but using StringBuilder to make it fast.
For example, if a string is 'AA' then it would be '%A%A%'. If it is 'XYZ' then it would be '%X%Y%Z%'
String foo = "VWXYZ";
foo = "%" + foo.replaceAll("(.)","$1%");
System.out.println(foo);
Output:
%V%W%X%Y%Z%
You don't need a StringBuilder. The compiler will take care of that simple concatenation prior to the regex for you by using one.
Edit in response to comment below:
replaceAll() uses a Regular Expression (regex).
The regex (.) says "match any character, and give me a reference to it" . is a wildcard for any character, the parenthesis create the backreference. The $1 in the second argument says "Use backreference #1 from the match".
replaceAll() keeps running this expression over the whole string replacing each character with itself followed by a percent sign, building a new String which it then returns to you.
Try something like this:
String test = "ABC";
StringBuilder builder = new StringBuilder("");
builder.append("%");
for (char achar : test.toCharArray()) {
builder.append(achar);
builder.append("%");
}
System.out.println(builder.toString());
public static String escape(String s) {
StringBuilder buf = new StringBuilder();
boolean wasLetter = false;
for (char c: s.toCharArray()) {
boolean isLetter = Character.isLetter(c);
if (isLetter && !wasLetter) {
buf.append('%');
}
buf.append(c);
if (isLetter) {
buf.append('%');
}
wasLetter = isLetter;
}
return buf.toString();
}
StringBuilder sb = new StringBuilder("AAAAAAA");
for(int i = sb.length(); i >= 0; i--)
{
sb.insert(i, '%');
}
You may see this.
String s="AAAA";
StringBuilder builder = new StringBuilder();
char[] ch=s.toCharArray();
for(int i=0;i<ch.length;i++)
{
builder.append("%"+ch[i]);
}
builder.append("%");
System.out.println(builder.toString());
Output
%A%A%A%A%
I agree with #Brian Roach to add character to before and after but if you want to add any specific character then do like this
String source = "hello good old world";
StringBuffer res = new StringBuffer();
String[] strArr = tagList.split(" ");
for (String str : strArr) {
char[] stringArray = str.trim().toCharArray();
stringArray[0] = stringArray[0];
str = new String(stringArray);
//here you need to specify your first and last character which you want to set
res.append("#"+ str + "$").append(" ");
}
System.out.println("Result: " + res.toString().trim());
Output :- #hello$ #good$ #old$ #world$