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
Related
I'm trying to pick out the characters of a string that come just before and just after the part of the string that matches another string, creating a completely different string. I.e. when the method wordEnds(String str, String word) is called, and str = "XY1XY" and word = "XY", then the new string would be "11".
Here is what I have so far:
package codingBat;
public class CodingBat {
public static String wordEnds(String str, String
word) {
String newStr = null;
if(str.equals(word)) {
return "";
}
else if(!str.contains(word)) {
return "";
}
else {
for(int i = 0;i < str.length();i++) {
if((word.equals(str.substring(i,i+1)))){
newStr = newStr + (str.substring(i-1,i+2));
}
else {
return newStr;
}
}
return newStr;
}
}
}
Try to use regex, pattern for your example ll look like this XY.*XY. But You have to change the XYto the string parameter so it ll be pattern = str+"(.*)"+str. Then you can use the group and read the string from middle
Here is a code:
static String middleString(String str, String word) {
Pattern pattern = Pattern.compile(str + "(.*)" + str);
Matcher matcher = pattern.matcher(word);
matcher.matches();
return matcher.group(1);
}
This call:
System.out.println(middleString("XY", "XY11XY"));
Returns 11
I'm getting the URL(http://localhost:8080/CompanyServices/api/creators/2173) shown below from a HTTP Response header and I want to get the id after the creators which is 2173.
So, I deleted all non digits as shown below and got the following result : 80802173.
Is it a good approach to get the last 4 digits from the above set of digits?
One thing is that, this part localhost:8080 could change depending upon the server I deploy my application so I'm wondering if I should just grab something after creators/ ? If yes, then what is the best way to go about it?
public class GetLastFourIDs {
public static void main(String args[]){
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
String replaceString=str.replaceAll("\\D+","");
System.out.println(replaceString);
}
}
You can use regex API e.g.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
Pattern pattern = Pattern.compile("(creators/\\d+)");
Matcher matcher = pattern.matcher(str);
int value = 0;
if (matcher.find()) {
// Get e.g. `creators/2173` and split it on `/` then parse the second value to int
value = Integer.parseInt(matcher.group().split("/")[1]);
}
System.out.println(value);
}
}
Output:
2173
Non-regex solution:
public class Main {
public static void main(String[] args) {
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
int index = str.indexOf("creators/");
int value = 0;
if (index != -1) {
value = Integer.parseInt(str.substring(index + "creators/".length()));
}
System.out.println(value);
}
}
Output:
2173
[Update]
Incorporating comment by Andreas as follows:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
Pattern pattern = Pattern.compile("creators/(\\d+)");
Matcher matcher = pattern.matcher(str);
int value = 0;
if (matcher.find()) {
value = Integer.parseInt(matcher.group(1));
}
System.out.println(value);
}
}
Output:
2173
I was trying to get an int (serial number of a student) from a string looks like "122. Fardinabir 170213" , where "122" is his serial number.
Before this, I tried using nextInt() method with a Scanner of the String, but nextInt() failed to do the job.
Then I have tried this procces...
import java.util.Scanner;
public class tempfile {
public static void main(String[] args) {
int serial_int = 0;
String serial_st;
serial_st = find_serial("122. FardinAbir 170213") ;
System.out.println(serial_st);
serial_int = Integer.parseInt(serial_st);
System.out.println(serial_int);
}
public static String find_serial(String st)
{
String[] parts = st.split(" "); // the first serial part will remain in parts[0]
parts[0].replaceAll("[\\D]", ""); // As I know it will remove non integer and the pure int serial will remain
return parts[0];
}
}
But, replaceAll("[\\D]", "") is not working...
Can anyone please help me to solve this or find a way out to this job...
Thanks in advance...
String line = "122. FardinAbir 170213";
Pattern pattern = Pattern.compile("^(\\d+)");
Matcher matcher = pattern.matcher(line);
if(matcher.find()) {
int id = Integer.parseInt(matcher.group(1));
System.out.println(id);
}
Assuming you also want to get the rest of the string eventually you can use Regex groups
String line = "122. FardinAbir 170213";
Pattern pattern = Pattern.compile("(\\d+)\\.\\s+([^\\s]+)\\s+(\\d+)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
System.out.println("serial: " + matcher.group(1));
int serial = Integer.parseInt(matcher.group(1));
System.out.println("group 2: " + matcher.group(2));
System.out.println("group 3: " + matcher.group(3));
}
nextInt() probably did not work because scanner expects newline separation
Since you tried using nextInt it seems you just want leading digits, which means you can use the following regex code:
public static String find_serial(String st) {
Matcher m = Pattern.compile("^\\d+").matcher(st);
return (m.find() ? m.group() : null);
}
You could also rely in the serial ending with a period, though that doesn't validate that serial is all digits:
public static String find_serial(String st) {
int idx = st.indexOf('.');
return (idx > 0 ? st.substring(0, idx) : null);
}
This'll do:
public static int getSerialNumber() {
String id = "122. Fardinabir 170213";
int place = 0;
for(int i = 0; i < id.length();i++) {
if(id.charAt(i) == '.') {
place = i;
break;
}
}
return Integer.parseInt(id.substring(0, place));
}
EDIT: you can also do it like this:
public static int getSerialNumber(String name) {
return Integer.parseInt(name.substring(0, name.indexOf('.')));
}
thanks #Andreas for that solution.
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();
}
}
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