I'm trying to figure out how the str.replaceAll(string, newString) method works. I know how to use it, but I'm trying to figure out what goes on inside the method. Does it use multiple for loops and strings, or something more advanced than that? Ideas, pseudocode, and code examples would be lovely.
PS I've already searched this up, but it only shows how to use it, not how it works.
According to the source code for String#replaceAll:
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
It creates a Pattern and uses regex to replace the target with the replacement.
In case you want to know about the Matcher#replaceAll call:
public String replaceAll(String replacement) {
reset();
boolean result = find();
if (result) {
StringBuffer sb = new StringBuffer();
do {
appendReplacement(sb, replacement);
result = find();
} while (result);
appendTail(sb);
return sb.toString();
}
return text.toString();
}
Related
I'm trying to remove every sequence of () in my string.
For example my String is:
String a = "() a)";
And I want it to become
" a)"
When I tried this it gave me an infinite loop
public static String removeParentheses(String s) {
while (s.contains("()")) {
s = s.replaceAll("()", "");
}
return s;
}
String replaceAll method require regexp in parameter. In your case you provide empty group. To use string as parameter you can use replace method like:
public static void main(String[] args) {
String toChange = "asa()assaa()ass()asa()";
String result = toChange.replace("()", "");
assert Objects.equals(result, "asaassaaassasax");
}
Or change the regexp to correct form using \ character in way:
public static void main(String[] args) {
String toChange = "asa()assaa()ass()asa()";
String result = toChange.replaceAll("\\(\\)", "");
assert Objects.equals(result, "asaassaaassasax");
}
According the documentation of String.replaceAll, the first argument is a regular expression.
This means () is not being treated literally, it's being treated as an empty capture group, which effectively matches nothing. I think what you're looking for is the normal String.replace method. I'm aware that the names of these methods seem to imply that replace only replaces one instance while replaceAll replaces all of them, but this is not the case.
public static String removeParentheses(String s) {
return s.replace("()", "");
}
JDoodle deomonstrating code above
If for some reason you would like to continue using replaceAll instead, you can dynamically escape the pattern using Pattern.quote.
public static String removeParentheses(String s) {
String pattern = Pattern.quote("()");
return s.replaceAll(pattern, "");
}
JDoodle demonstrating code above
I am trying to duplicate backslash characters inside a string.
The string is a directory path!
I wrote a function, but it doesn't return a correct result!
When I tested the function with
C:\Users\Asus i7\Desktop\untitled1ghthr\src\sample\panda.mp3
it returns
C:\\User\s\Asus \i7\Desk\top\untitled1g\hth\r\src\\sample\panda.mp3
While i want it to return
C:\\Users\\Asus i7\\Desktop\\untitled1ghthr\\src\\sample\\panda.mp3
Code of the function
public StringBuffer add(String ch) {
StringBuffer str = new StringBuffer(ch);
for(int i=0;i<ch.length();i++){
if (ch.charAt(i)=='\\'){
str.insert(i, '\\');
}
}
return str;
}
Consider using Paths.get : documentation
The method you are trying to use will not work on all OS.
This is actually an exercise from CodingBat. The definition of the problem is as follows:
Given a string, if the string "del" appears starting at index 1, return a string where that "del" has been deleted. Otherwise, return the string unchanged.
delDel("adelbc") → "abc"
delDel("adelHello") → "aHello"
delDel("adedbc") → "adedbc"
My work is as follows:
public String delDel(String str) {
String del = "del";
if (str.indexOf(del, 1) == 1){
str.replaceFirst("del", null);
}
return str;
}
It works fine for most of the cases, but I get NullPointerException in "adelbc", "adelHello" and "adel" cases. I can't quite understand why.
If you look closely in the OpenJDK sources, you'll note that replaceFirst delegates work to the regexp functions, including this one for replacing step:
public String replaceFirst(String replacement) {
if (replacement == null)
throw new NullPointerException("replacement");
reset();
if (!find())
return text.toString();
StringBuffer sb = new StringBuffer();
appendReplacement(sb, replacement);
appendTail(sb);
return sb.toString();
}
Note that replacement can not be null. I assume the behaviour is going to be similar in other implementations of the JRE. Please use "" - empty string - instead of null as the replacement.
Also as mentioned in the comments by cricket_007 you want to save the result of replaceFirst for returning, since the original string will not be affected (all Strings in Java are immutable). The final piece of code:
public String delDel(String str) {
String del = "del";
if (str.indexOf(del, 1) == 1){
return str.replaceFirst("del", "");
}
return str;
}
I need a advice (both in java & .net) for the following piece of code.
public void method(bool value)
{
String someString;
//some code
if (value)
{
//some code
...
someString = "one" + value;
}
else
{
//some code
...
someString = "two" + value;
}
}
Which one is advisable and why? either code like above or code like
someString = "onetrue";
someString = "twofalse";
After compilation and optimization by JDK, method will look like:
public static String method(boolean value) {
String someString;
if (value) {
StringBuilder sb = new StringBuilder();
sb.append("one");
sb.append(value);
someString = sb.toString();
} else {
StringBuilder sb = new StringBuilder();
sb.append("two");
sb.append(value);
someString = sb.toString();
}
return someString;
}
If this code is invoked very frequently, it could bring a performance impact, compared to the second version. In each case a new StringBuilder is constructed and three methods are invoked on it. And boolean should be converted to an object before calling append. While in the second version we just return constant. Everything depends on how often this code is called.
Neither will make any difference it's purely style.
Since you have // some other code I'd just stick with the first. If you only had one line in each branch then either is ok.
At a high level they both are the same but if you look down at lower levels, I would advise to using the method:
someString = "onetrue";
someString = "twofalse";
This is because when you do "one" + value, the value is actually a bool and the toString() method of the bool object will be called to add to the string. Basically just adding another step opposed to just specifying what to add to the string.
I have a recursive method that reversed a string (HW assignment, has to be recursive). I did it....but its only returning the value of the string after the first pass. By analyzing the output after each pass i can see it does do its job correctly. heres my code, and the output i get below it:
String s = "Hello, I love you wont you tell me your name?";
int k=0;
public String reverseThisString(String s) {
if(k!=s.length()) {
String first =s.substring(0,k)+s.charAt(s.length()-1);
String end = ""+s.substring(k, s.length()-1);
k++;
s=first+end;
System.out.println(s);
this.reverseThisString(s);
}
return s;
}
output:
?Hello, I love you wont you tell me your name
I think you need to change this:
this.reverseThisString(s);
to this:
return this.reverseThisString(s);
otherwise the result of the method call is simply discarded.
I would also recommed that you change k to be a parameter to the method rather than a member.
Like Mark said, you forgot the return statement.
Also, there is an easier way to reverse a string (which is my current homework too :P )
public String reverse(String s) {
if(s.length() <= 1)
return s;
return reverse(s.substring(1))+s.charAt(0);
}