How do I replace a string while maintaining the case? - java

I want to replace a string by removing the s in the end
Example
Sticks -> Stick
STiCKs -> STiCK
StICks -> StICK
sticks -> stick
while using the
string.replace("sticks", "stick");
doesn't maintain case as it is case sensitive, so I'm seeking for a better option.

You could use a very simple regex for this mission.
(?i) guarantees that your regex will be treated case insensitive
Demo : (?i)(stick)s
Ideone Java Demo
string.replaceAll("(?i)(stick)s", "$1");

One possible solution is regular expressions:
StringBuffer sb = new StringBuffer();
Matcher matcher = Pattern.compile("(stick)s", Pattern.CASE_INSENSITIVE) .matcher(inputString);
while(matcher.find()) {
matcher.appendReplacement(sb, matcher.group(1));
}
matcher.appendTail(sb);
String outputString = sb.toString();
Edit: this is more or less what does String::replaceAll, but replaceAll doesn't give a case insensitive option.

If you just need to remove the 's' at the end of the String you can simply use substring method like this:
String myString = "sTiCks";
myString = myString.substring(0, myString.length()-1);
// Result "sTiCk"
If you need to remove a char or String from your String not knowing where this part will be, you can try something this:
String myString = "sTiCks";
// Part you want to delete
String stringToDelete = "Ck";
// Find where that part starts inside your String
int index = myString.indexOf(stringToDelete);
// If found, use substring method to take only what is before and after that part
if (index >= 0)
myString = myString.substring(0, index) + myString.substring(index + stringToDelete.length(), myString.length());
// Result "sTis"
This will delete the desired part only the first time it finds it. But if the part you want to delete appears more than once in your String you can modify the code to this:
String myString = "sTiCks";
// Part you want to delete
String stringToDelete = "s";
int index;
while ((index = myString.indexOf(stringToDelete)) >= 0)
myString = myString.substring(0, index) + myString.substring(index + stringToDelete.length(), myString.length());
// Result "TiCk"
I hope one of these solutions fits your case.

I don't really get why all the answers so far are so complex. You can just check the last character and if it's a s (or S) you use String#substring (documentation) and leave out the last character:
String text = "STiCks";
char lastCharacter = text.charAt(text.length() - 1);
if (lastCharacter == 'S' || lastCharacter == 's') {
text = text.substring(0, text.length() - 1);
}
If you want to apply that method to multiple words, for example in a sentence, tokenize the sentence first. Then apply the method to each word and rebuild the sentence.
String sentence = StiCks are nice, I like sticks"
String[] words = sentence.split(" ");
StringJoiner joiner = new StringJoiner(" ");
for (String word : words) {
joiner.add(removePluralSuffix(word));
}
String result = joiner.toString();
or the same with Streams:
String result = Arrays.stream(sentence.split(" "))
.map(this::removePluralSuffix)
.collect(Collectors.joining(" "));

Related

Is there option to change string in second argument of replaceAll, accessed by capture group

I write a program replacing String in which words are delimited by '-' or '_' (word1-word2-word3... or word1_word2_word3... or any combination of those), to camel case format: word1Word2Word3...
I wanted to do it like this:
str.replaceAll("[-_]([a-zA-Z0-9])", "$1".toUpperCase()); and half of it sorta works: I get resutl of: word1word2word3... - looks like, toUpperCase() didn't have any effect, so my questions are: why is it so and how to make it work - preferably using replaceAll()
Sample input: word1_word2_word3
Expected output: word1Word2Word3
Use the replaceAll(Function<MatchResult, String>) method of Matcher:
str = Pattern.compile("[-_]([a-zA-Z0-9])")
.matcher(str)
.replaceAll(mr -> mr.group(1).toUpperCase());
See live demo showing that:
String str = "word1_word2-word3";
str = Pattern.compile("[-_]([a-zA-Z0-9])")
.matcher(str)
.replaceAll(mr -> mr.group(1).toUpperCase());
System.out.println(str);
Outputs:
word1Word2Word3
Here is working solution for your mentioned problem :
public static void main(String[] args) {
char[] deliminators = {'-', '_'};
String input = "word1-word2-word3_word1_word2_word3";
char[] output = "word1-word2-word3_word1_word2_word3".toCharArray();
int index = 0;
for (char element : input.toCharArray()) {
if (ArrayUtils.contains(deliminators, element)) {
ArrayUtils.remove(output, index);
index++;
output[index] = Character.toUpperCase(output[index]);
continue;
}
index++;
}
output[0] = Character.toUpperCase(output[0]);
String.valueOf(output).replaceAll("-", "").replaceAll("_", "");
System.out.println(String.valueOf(output).replaceAll("-", "").replaceAll("_", ""));
}
Kindly acknowledge , it should work directly for your use-case.

Remove everything in a string after a second space if there is one

Lets say I have this text: Thundering Blow I. What I need is something that makes it look like Thundering Blow - Removing the roman number at the end of the string.
I have tried trim() and some substring() methods but they all keep returning: Thundering Blow I back to me. Maybe it could remove everything after a I in the string? Would also be fine, but I cant seem to find a way to fix it.
You need this, removes all characters after second space
String s = "Thundering Blow I";
int k = s.indexOf(" ", s.indexOf(" ") + 1);
String res = s.substring(0,k);
System.out.println(res);
String newStr = s.substring(0, s.lastIndexOf(" "));
This is the whole code:
String s = "ThunderingI";
s = s.trim();
int ind = s.lastIndexOf(" ");
if (ind > 0) {
s = s.substring(0, ind).trim();
}
System.out.println(s);
You can split the string then concatenate a new string with index 0 and 1.
Easiest solution :)..
String[] tempArray = orgStr.split(" ");
String newStr = tempArray[0] + " " + tempArray[1];
You could try this.
String a = "Thundering Blow I";
String[] b = a.split(" ");
System.out.println(b[0]+" "+b[1]);
This will remove a single Roman numeral from the end of a string, if it exists:
String input = "Thundering Blow returning MMXVI";
input = input.replaceAll("\\s[CDILMVX]*$", "");
MMXVI is 2016 in Roman numerals in case you are wondering.

Return a substring which is almost the same as the original String

I have a String literal that contains a sequence of [a-z] characters followed by a digit character. I want to create a new String literal whose contents will be the same as the old String except the last digit character. How can I do this in the most optimal way in Java?
eg:
String str = "sometext2";
String newString = "sometext5"; //The digit part is dynamic and I have that value already computed
return newString
You could try this regex
\d*$ // 0 or more digits at the end of the string
Example:
#Test
public void replaceTrailingDigits() {
String str = "sometext2".replaceFirst("\\d*$", Integer.toString(5));
Assert.assertEquals("sometext5", str);
str = "sometext226782".replaceFirst("\\d*$", Integer.toString(897623));
Assert.assertEquals("sometext897623", str);
str = "sometext".replaceFirst("\\d*$", Integer.toString(4));
Assert.assertEquals("sometext4", str);
}
As you see in the 3rd test, the regexp allow to append the new number if the original str does not have any tailing digits. If you want to prevent that then you could change the mutiplicity to one or more , i.e. \d+$
Try this
StringBuilder sb = new StringBuilder();
sb.append(str.subString(0, str.length()-1)).append(digit).toString();
if(str != null && !str.isEmpty())
return (str.substring(0, str.length() - 1)).concat(YOUR_OTHER_DIGIT);
else
return str; // Handle appropriately what action you want if str is null or empty
If it is only one digit, use substrings
return str.substring(str.length() - 1) + nextDigit;
If there are several digits, use a regex
return str.replaceAll("[0-9]+", "" + nextNumber)
If this is in a tight loop, reuse the regex instead of using replaceAll
If it is only one digit, you can do that:
return originalString.substring(0, originalString.length()-1) + newDigit;

Trim a string in java to get first word

I have a String "Magic Word". I need to trim the string to extract "Magic" only.
I am doing the following code.
String sentence = "Magic Word";
String[] words = sentence.split(" ");
for (String word : words)
{
System.out.println(word);
}
I need only the first word.
Is there any other methods to trim a string to get first word only if space occurs?
String firstWord = "Magic Word";
if(firstWord.contains(" ")){
firstWord= firstWord.substring(0, firstWord.indexOf(" "));
System.out.println(firstWord);
}
You could use String's replaceAll() method which takes a regular expression as input, to replace everything after the space including the space, if a space does indeed exist, with the empty string:
String firstWord = sentence.replaceAll(" .*", "");
This should be the easiest way.
public String firstWord(String string)
{
return (string+" ").split(" ")[0]; //add " " to string to be sure there is something to split
}
modifying previous answer.
String firstWord = null;
if(string.contains(" ")){
firstWord= string.substring(0, string.indexOf(" "));
}
else{
firstWord = string;
}
String input = "This is a line of text";
int i = input.indexOf(" "); // 4
String word = input.substring(0, i); // from 0 to 3
String rest = input.substring(i+1); // after the space to the rest of the line
A dirty solution:
sentence.replaceFirst("\\s*(\\w+).*", "$1")
This has the potential to return the original string if no match, so just add a condition:
if (sentence.matches("\\s*(\\w+).*", "$1"))
output = sentence.replaceFirst("\\s*(\\w+).*", "$1")
Or you can use a cleaner solution:
String parts[] = sentence.trim().split("\\s+");
if (parts.length > 0)
output = parts[0];
The two solutions above makes assumptions about the first character that is not space in the string is word, which might not be true if the string starts with punctuations.
To take care of that:
String parts[] = sentence.trim().replaceAll("[^\\w ]", "").split("\\s+");
if (parts.length > 0)
output = parts[0];
You May Try This->
String newString = "Magic Word";
int index = newString.indexOf(" ");
String firstString = newString.substring(0, index);
System.out.println("firstString = "+firstString);
We should never make simple things more complicated. Programming is about making complicated things simple.
string.split(" ")[0]; //the first word.

how to find before and after sub-string in a string

I have a string say 123dance456 which I need to split into two strings containing the first sub-string before the sub-string dance (i.e. 123) and after the sub-string dance (i.e. 456). I need to find them and hold them in separate string variables, say String firstSubString = 123; and String secondSubString = 456;.
Is there any given String method that does just that?
You can use String.split(String regex). Just do something like this:
String s = "123dance456";
String[] split = s.split("dance");
String firstSubString = split[0];
String secondSubString = split[1];
Please note that if "dance" occurs more than once in the original string, split() will split on each occurrence -- that's why the return value is an array.
You can do this:
String str = "123dance456";
String substr = "dance";
String before = str.substring(0, str.indexOf(substr));
String after = str.substring(str.indexOf(substr) + substr.length());
Or
String str = "123dance456";
String substr = "dance";
String[] parts = str.split(substr);
String before = parts[0];
String after = parts[1];
It is noteworthy that the second answer not work if we have more than one occurrence of the substring. To that end, if we only want the first one to be recognized, it would be safer to call split with a limit:
String[] parts = str.split(substr, 2);
which ensures that the returned array has at most two elements. Also, since split will interpret its input as a regular expression we have to be wary of invalid regular expression syntax. As such, I would much rather the first solution, since it works irrespective of the composition of the original substring.
To make the first answer more efficient -- as it is my preferred answer -- then, we would need to remember the position of the substring:
final int position = str.indexOf(substr);
if (position >= 0) {
//if the substring does occur within the string, set the values accordingly
before = str.substring(0, position);
after = str.substring(position + substr.length());
} else {
//otherwise, default to the empty string (or some other value)
before = "";
after = "";
}
It always pays to pay attention to these little edge cases.
If you are using commons-lang see StringUtils.substringAfter()
Easiest is to use the split method as the other answers suggest. You can also use a Matcher and a Pattern for a more general approach:
String str = "123dance456";
String splitter = "dance";
Pattern p = Pattern.compile("(.*?)" + splitter + "(.*)");
Matcher m = p.matcher(str);
if (m.matches()) {
firstSubString = m.group(1); // may be empty
secondSubString = m.group(2); // may be empty
} else {
// splitter not found in str
}
String[] data = new String("123dance456").split("dance");
Using the Scanner is a nice alternative:
Scanner scanner = new Scanner( "123dance456" ).useDelimiter( "dance" );
if ( scanner.hasNext() )
System.out.println( scanner.next() );
if ( scanner.hasNext() )
System.out.println( scanner.next() );
It is quite convenient to process the tokens as a stream and simply ask via hasNext() if new tokens are available. Also you get nice conversions from the Scanner, even localised, like:
Scanner scanner = new Scanner( "123dance456" ).useDelimiter( "dance" );
System.out.println( scanner.nextDouble() * scanner.nextDouble() );

Categories