How can I replace string between first & and next & only:
public class Test02 {
public static void main(String[] args) {
String xyz = "&axy=asdsd&ram=2 gb4 gb&asd=sdsd&";
String x = xyz.replaceAll("&ram=.*&", "&ram=8 gb&");
System.out.println(x);
}
}
my input - &axy=asdsd&ram=2 gb4 gb&asd=sdsd&
my output - &axy=asdsd&ram=8 gb&
but I want- &axy=asdsd&ram=8 gb&asd=sdsd&
only want to change middle part.
I am making a search filter. If any API for building query exists I would love to know.
Thanks bobble,
this worked... '.?' instead of '.' ..
public class Test02 {
public static void main(String[] args) {
String xyz = "&axy=asdsd&ram=2 gb4 gb&asd=sdsd&";
String x = xyz.replaceAll("(&ram=.*?)&", "&ram=8 gb&");
System.out.println(x);
}
}
now out put-- &axy=asdsd&ram=8 gb&asd=sdsd&
You can use the split method on your String to break it into its tokens with a given delimiter. Then just replace whatever index you want with the new desired value.
Something like this (not tested)
String text = "A&B&C";
String delim = "&";
String[] elements = text.split(delim);
elements[0]= "D";
String result = "";
for (String token : elements) {
result += token + delim;
}
System.out.println(result.substring(0, result.length() - delim.length())); // "D&B&C"
public static void main(String[] args) {
String xyz = "&axy=asdsd&ram=2 gb4 gb&asd=sdsd&";
int firstAndPosition =xyz.indexOf('&',1);
int secondAndPosition =xyz.indexOf('&',firstAndPosition+1);
String stringToReplace = xyz.substring(firstAndPosition, secondAndPosition +1);
//The do your stuff
String x = xyz.replaceAll(stringToReplace, "&ram=8 gb&");
System.out.println(x);
}
}
You need to use a negated character class [^&] matching any character but a & with a * quantifier (zero or more occurrences) and leverage String#replaceFirst() method to only perform one replacement:
String xyz = "&axy=asdsd&ram=2 gb4 gb&asd=sdsd&";
String x = xyz.replaceFirst("&ram=[^&]*&", "&ram=8 gb&");
System.out.println(x);
// => &axy=asdsd&ram=8 gb&asd=sdsd&
See IDEONE demo
Related
I'm trying to print out a string with spaces on either side of each char in the string
so if I have
String s = "abcde"
it would create something like this
a b c d e
with a space before the first char and three between each char.
I just haven't been able to find a way to do this with my knowledge.
Update
Updated requirement:
I failed to realize that I need something that add one place in front
of the first term and then 3 spaces between each term.
_0___0___0___0___0_ for example.
For the updated requirement, you can use yet another cool thing, String#join.
public class Main {
public static void main(String[] args) {
String s = "abcde";
String result = "_" + String.join("___", s.split("")) + "_";
System.out.println(result);
}
}
Output:
_a___b___c___d___e_
Original answer
There can be so many ways to do it. I find it easier to do it using Regex:
public class Main {
public static void main(String[] args) {
String s = "abcde";
String result = s.replaceAll(".", " $0 ");
System.out.println(result);
}
}
Output:
a b c d e
The Regex, . matches a single character and $0 replaces this match with space + match + space.
Another cool way is by using Stream API.
import java.util.Arrays;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
String s = "abcde";
String result = Arrays.stream(s.split(""))
.map(str -> " " + str + " ")
.collect(Collectors.joining());
System.out.println(result);
}
}
Output:
a b c d e
A super simple example, that doesn't handle a multitude of potential input scenarios.
public static void main(String[] args)
{
String s = "abcde";
for (int i = 0; i < s.length(); ++i) {
System.out.print("_" + s.charAt(i));
}
System.out.println("_");
}
NOTE: used an underscore rather than a space in order to allow visual check of the output.
Sample output:
_a_b_c_d_e_
Rather than direct output, one could use a StringBuilder and .append to a builder instead, for example.
Using StringBuilder:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); ++i) {
sb.append('_').append(s.charAt(i));
}
sb.append('_');
System.out.println(sb.toString());
Based on a comment where the desired output is slightly different (two internal spaces, one leading and trailing space), this suggests an alternative approach:
public static String addSpace(String inp) {
StringBuilder sB = new StringBuilder();
String string = inp.trim();
String div = "___"; // spaces, or whatever
sB.append('_'); // add leading space
for(int index = 0; index < string.length(); ++index) {
sB.append(string.charAt(index))
.append(div); // two spaces
}
sB.setLength(sB.length() - (div.length() - 1) );
return (sB.toString());
}
NOTE: again using an underscore to allow for easier debugging.
Output when div is set to 3 underscores (or spaces):
_0___0___0___1___0___1___1___0_
You can define an empty string : result = “”;
Then go through the string you want to print with foreach loop With the function toCharArray()
(char character : str.toCharArray())
And inside this loop do ->
result += “ “ + character;
String result = s.chars().mapToObj(
Character::toString
).collect(Collectors.joining(" "));
Similar to the loop versions, but uses a Stream.
Another one liner to achieve this, by splitting the String into String[] of characters and joining them by space:
public class Main {
public static void main(String[] args) {
String s = "abcde";
System.out.println(" " + String.join(" ", s.split("")) + " ");
}
}
Output:
a b c d e
Edit:
The above code won't work for strings with Unicode codepoints like "👦ab😊", so instead of splitting on empty string, the split should be performed on regex: "(?<=.)".
public class Main {
public static void main(String[] args) {
String s = "abcde";
System.out.println(" " + String.join(" ", s.split("(?<=.)")) + " ");
}
}
Thanks to #saka1029 for pointing this out.
You can use Collectors.joining(delimiter,prefix,suffix) method with three parameters:
String s1 = "abcde";
String s2 = Arrays.stream(s1.split(""))
.collect(Collectors.joining("_+_", "-{", "}-"));
System.out.println(s2); // -{a_+_b_+_c_+_d_+_e}-
See also: How to get all possible combinations from two arrays?
In this code, we remove the substring "luna" from email string using the .replaceFirst method. We are removing the characters in between + and #. But this happens only in the first instance because we used .replaceFirst. What if we wanted to target the second instance of + and # to remove "smith"?
Our output now is alice+#john+smith#steve+oliver# but we want alice+luna#john+#steve+oliver#
public class Main {
public static void main(String[] args) {
String email = "alice+luna#john+smith#steve+oliver#";
String newEmail = email.replaceFirst("\\+.*?#", "");
System.out.println(newEmail);
}
}
You can find the second + like so:
int firstPlus = email.indexOf('+');
int secondPlus = email.indexOf('+', firstPlus + 1);
(You need to handle the case that there aren't two +s to find, if necessary).
Then find the following #:
int at = email.indexOf('#', secondPlus);
Then stitch it back together:
String newEmail = email.substring(0, secondPlus + 1) + email.substring(at);
or
String newEmail2 = new StringBuilder(email).delete(secondPlus + 1, at).toString();
Ideone demo
Unfortunately Java doesn't have methods like replace second, replace third etc. You can either replaceAll (which will replace all occurences) OR invoce replaceFirst again on the already replaced string. That's basically replacing the second. If you want to replace ONLY the second - then you can do it with substrings or do a regex matcher and iterate on results.
public static void main(String[] args) {
String email = "alice+luna#john+smith#steve+oliver#";
String newEmail = email.replaceFirst("\\+.*?#", "");
newEmail = newEmail .replaceFirst("\\+.*?#", ""); //this replaces the second right? :)
newEmail = newEmail .replaceFirst("\\+.*?#", ""); // replace 3rd etc.
System.out.println(newEmail);
}
You can alternate value of parameter n in following replaceNth method to 2, 3 to perform exactly the same operation as that of replaceSecond or replaceThird. ( Note: this method can be applied in any other value of n. If nth pattern do not exist , it simply return given string ).
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static String replaceNth(String str, int n, String regex, String replaceWith) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
while (m.find()) {
n--;
if (n == 0) {
return str.substring(0,m.start() + 1)+ replaceWith + str.substring(m.end() - 1);
}
}
return str;
}
public static void main(String args[]) {
String email = "alice+luna#john+smith#steve+oliver#";
System.out.println(replaceNth(email, 2, "\\+.*?#", ""));
}
}
I think it is better to encapsulate this logic into separate method, where String and group position are arguments.
private static final Pattern PATTERN = Pattern.compile("([^+#]+)#");
private static String removeSubstringGroup(String str, int pos) {
Matcher matcher = PATTERN.matcher(str);
while (matcher.find()) {
if (pos-- == 0)
return str.substring(0, matcher.start()) + str.substring(matcher.end() - 1);
}
return str;
}
Additionally, you can add more methods, to simplify using this util; like removeFirst() or removeLast()
public static String removeFirst(String str) {
return removeSubstringGroup(str, 0);
}
public static String removeSecond(String str) {
return removeSubstringGroup(str, 1);
}
Demo:
String email = "alice+luna#john+smith#steve+oliver#";
System.out.println(email);
System.out.println(removeFirst(email));
System.out.println(removeSecond(email));
System.out.println(removeSubstringGroup(email, 2));
System.out.println(removeSubstringGroup(email, 3));
Output:
alice+luna#john+smith#steve+oliver#
alice+#john+smith#steve+oliver#
alice+luna#john+#steve+oliver#
alice+luna#john+smith#steve+#
alice+luna#john+smith#steve+oliver#
Ideone demo
Below is my string
/downloadAPK/D:/coinFiles/Coin-v1.1.8.apk
I want to get the value after 2nd slash(/) which is
D:/coinFiles/Coin-v1.1.8.apk
How should I do this?
Note :
I am getting this string in my rest call in variable restOfTheUrl
#RequestMapping(value="/downloadAPK/**", method = RequestMethod.GET)
public void downloadFile(HttpServletResponse response, HttpServletRequest request) throws IOException {
String restOfTheUrl = (String) request.getAttribute(
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
}
I want to get the complete file location
Even a better and simple solution \\/.*?\\/(.*)
Regex Demo
\\/.*?\\/(.*) : \\/.*?\\/ match the first two / and content between
(.*) : capture whatever is after first two /
String s = "/downloadAPK/D:/coinFiles/Coin-v1.1.8.apk";
String result=s.replaceAll("\\/.*?\\/(.*)", "$1");
System.out.println(result);
Output :
D:/coinFiles/Coin-v1.1.8.apk
You can use a regex with replceAll if there is always one : in the input
String s = "/downloadAPK/D:/coinFiles/Coin-v1.1.8.apk";
String result=s.replaceAll(".*([A-Za-z]:.*)", "$1");
System.out.println(result);
Output :
D:/coinFiles/Coin-v1.1.8.apk
.*([A-Za-z]:.*) : .* matches any character
([A-Za-z]:.*) : [A-Za-z] match a character like D
() : is a capturing group which is represented as $1
:.* : will capture all after :
Otherwise
String s = "/downloadAPK/D:/coinFiles/Coin-v1.1.8.apk";
// find first index of /
int index =s.indexOf("/");
// find second index of /
index=s.indexOf("/", index+1);
// fetch substring from second index+1 of /
System.out.println(s.substring(index+1));
Output :
D:/coinFiles/Coin-v1.1.8.apk
If you are sure, always colon(:) will exist in string, then you can use this.
import java.io.*;
public class Test {
public static void main(String args[]) {
String str = new String("/downloadAPK/D:/coinFiles/Coin-v1.1.8.apk");
String subStr1 = new String(":");
System.out.println("value "+ str.substring(str.indexOf( subStr1 )-1));
}
}
output:
value D:/coinFiles/Coin-v1.1.8.apk
This code for without colon (:)
public class HelloWorld{
public static void main(String args[]) {
String str = new String("/downloadAPK/D:/coinFiles/Coin-v1.1.8.apk");
System.out.println("before value" + str);
str = getPattern(str, 2);
System.out.println("\nAfter value "+ str);
}
public static String getPattern(String str, Integer pos) {
for(int i = 0; i< pos; i ++) {
str = str.substring(str.indexOf("/") +1);
}
return str;
}
}
Output
before value/downloadAPK/D:/coinFiles/Coin-v1.1.8.apk
After value D:/coinFiles/Coin-v1.1.8.apk
You can iteratively find the index. You could also write a recursive version, but this does not perform the substring until the final step; which means it will not pollute the String pool.
public class StringUtil {
public static void main(String[] args) {
String path = "/downloadAPK/D:/coinFiles/Coin-v1.1.8.apk";
System.out.println(substring2(path, "/", 2)); // D:/coinFiles/Coin-v1.1.8.apk
String test = "this---is---a---test";
System.out.println(substring2(test, "---", 3)); // test
}
public static String substring2(String src, String str, int offset) {
if (offset <= 0) {
return src;
}
int index = -1, pos = 0;
while (pos++ < offset) {
index = src.indexOf(str, index + 1);
}
return src.substring(index + str.length(), src.length());
}
}
Here is a StringTokenizer version which handles indexing for you.
import java.util.Enumeration;
import java.util.StringTokenizer;
public class StringUtil {
public static void main(String[] args) {
String path = "/downloadAPK/D:/coinFiles/Coin-v1.1.8.apk";
System.out.println(substring2(path, "/", 1)); // D:/coinFiles/Coin-v1.1.8.apk
String test = "this---is---a---test";
System.out.println(substring2(test, "---", 3)); // test
}
public static String substring2(String src, String delim, int offset) {
StringTokenizer tokenizer = new StringTokenizer(src, delim);
while (offset-- > 0 && tokenizer.hasMoreTokens()) {
tokenizer.nextToken();
}
return join(tokenizer, delim);
}
public static <T> String join(Enumeration<T> enumeration, String delim) {
StringBuffer buff = new StringBuffer();
while (enumeration.hasMoreElements()) {
buff.append(enumeration.nextElement());
if (enumeration.hasMoreElements()) {
buff.append(delim);
}
}
return buff.toString();
}
}
say I'm given a set of strings that looks like this:
0,test0,dummy
1,test,dummy
2,test1,dummy
3,test2,dummy
4,test3,dum,dum,dummy
I wrote code that can return only what's before the last ",":
public class RandomTest {
public static void main(String[] args) {
String testFile = "synsets11.txt";
In testIn = new In(testFile);
while (testIn.hasNextLine()) {
String line = testIn.readLine();
String result = line.substring(0, line.lastIndexOf(","));
List<String> synList = Arrays.asList(result.split(","));
for (String i : synList) {
System.out.println(i);
}
}
}
}
What I intended to do was only return the part of the string that was between the first and second "," characters, so my code above doesn't work for the last line of text. How do I only return what's between the first and second comma?
In this case, only test0, test, test1, test2, and test3.
thanks!
use split() method like this :
public static void main(String[] args) {
String s = "0,prop,dummy";
System.out.println(s.split(",")[1]);
}
O/P:
prop
NOTE : You have to check whether the String contains atleast 1 , (unless you want an ArrayIndexOutOfBoundsException :P)
Rather than using lastIndexOf, use indexOf twice:
int pos = line.indexOf(',', line.indexOf(',')+1);
String result = line.substring(0, pos);
You could use string.replaceAll function.
string.replaceAll("(?m)^[^,]*,|,.*", "");
DEMO
String s = "0,test0,dummy\n" +
"1,test,dummy\n" +
"2,test1,dummy\n" +
"3,test2,dummy\n" +
"4,test3,dum,dum,dummy";
System.out.println(s.replaceAll("(?m)^[^,]*,|,.*", ""));
What about StringTokenizer?
public class RandomTest {
public static void main(String[] args) {
String testFile = "synsets11.txt";
In testIn = new In(testFile);
StringTokenizer stok = null;
while (testIn.hasNextLine()) {
String line = testIn.readLine();
stok = new StringTokenizer(line,",");
for(int i = 0; i< stok.countTokens() ; i++){
String str = st.nextToken();
if( i == 1){
System.out.println(str);
}else if( i > 1){break;}
}// for
}// while
}//main
}//class
I'm trying to create a method that will accept 2 strings as arguments. The first string will be a phrase, the second also a prhase. What I want the method to do is to compare both strings for matching chars. If string 2 has a char that is found in string 1 then replace string 2's instance of the char with an underscore.
Example:
This is the input:
phrase1 = "String 1"
phrase2 = "Strone 2"
The output string is called newPhrase and it will have the string built from the underscores:
newPhrase = "___one 2"
Its not working for me I am doing something wrong.
public class DashedPhrase
{
public static void main(String[] args)
{
dashedHelp("ABCDE","ABDC");
}
public static String dashedHelp(String phrase1, String phrase2)
{
String newPhrase = "_";
for(int i = 0; i < phrase.length(); i++)
{
if(phrase.charAt(i) == phrase2.charAt(i))
{
newPhrase.charAt(i) += phrase2.charAt(i);
}
}
System.out.print(newPhrase);
return newPhrase;
}
}
To make it easier for you to understand, you can use StringBuilder and its method setCharAt().
Notice the i < phrase1.length() && i < phrase2.length() in the condition for the for loop. This is to make sure you don't get any ArrayIndexOutOfBounds exception.
public static void main(String[] args)
{
System.out.println("ABCDE");
System.out.println("ABDC");
dashedHelp("ABCDE","ABDC");
System.out.println();
System.out.println();
System.out.println("String 1");
System.out.println("Strone 2");
String phrase1 = "String 1";
String phrase2 = "Strone 2";
dashedHelp(phrase1, phrase2);
}
public static String dashedHelp(String phrase1, String phrase2)
{
StringBuilder newPhrase = new StringBuilder(phrase1);
for(int i = 0; i < phrase1.length() && i < phrase2.length(); i++)
{
if(phrase1.charAt(i) == phrase2.charAt(i))
{
newPhrase.setCharAt(i, '_');
}
}
System.out.print(newPhrase);
return newPhrase.toString();
}
Output:
ABCDE
ABDC
__CDE
String 1
Strone 2
___i_g_1
newPhrase.charAt(i) doesn't let you replace a character, it just returns it. Java's Strings are immutable. I you want to change it you should use StringBuilder. Look into the replace(int start, int end, String str) method.
Since you need to return a string that has the same length as phrase2, you need to iterate over each character of phrase2, and replace the matching characters of both phrases. And, of course, if phrase2 is longer than phrase1, you need to include the remaining characters in the answer. You can try this:
public static String dashedHelp(String phrase1, String phrase2) {
String ans = "";
String subChar = "_";
int i;
for(i = 0; i<phrase2.length(); i++) {
if(i<phrase1.length() && phrase1.charAt(i) == phrase2.charAt(i))
ans += subChar;
else
ans += phrase2.charAt(i);
}
return ans;
}
Hope it helps
Of course, if you need to output phrase1 with underscores in the places where phrase2 has equal characters, you can interchange phrase2 with phrase1 in the above code.
Testing it
The complete class would look like this:
public class MyClass {
public static String dashedHelp(String phrase1, String phrase2) {
// The method code goes here
}
public static void main(String[] args) {
System.out.println(dashedHelp("String 1", "Strone 2"));
}
}
The output of this program is ___o_e_2. This matches (approximately) your desired output.
The code in the example won't even compile.
newPhrase.charAt(i) += phrase2.charAt(i);
That's a bad assignment. It's the same as writing
newPhrase.charAt(i) = newPhrase.charAt(i) + phrase2.charAt(i);
but the expression on the left side of the '=' isn't something to which you can properly assign a value.