Java - Case insensitive split WITH VARIABLE splitting string - java

program test
so I have a program that will be given two strings as arguments: base and remove. It has to take out remove from base. I am using the split method to remove the second string from the first. However, the case on the chars of the second string should not matter, while the case of the first string must be preserved. I found a lot of ways to do this when you define the remove string in the program as a String literal: I can use ?i for example, but because remove is coming in as an argument and not a literal that I am defining in the program, this isn't working. Please check my attached picture so that you can see exactly where this is failing. Appreciate the help.
public String withoutString(String base, String remove) {
String array[] = base.split(remove);
String result = "";
for(int i = 0; i<array.length;i++)
result+= array[i];
return result;
}

Use a regex pattern with CASE_INSENSITIVE and LITERAL flags:
return Pattern.compile(remove, Pattern.CASE_INSENSITIVE | Pattern.LITERAL)
.matcher(base).replaceAll("");

String.replaceAll() method accepts regex you can use directly like:
return base.replaceAll("(?i)(" + remove +")[\s]*", "")

Related

How to format and replace groups using RegEx (or Maybe not?) (Java)

output = output.replaceAll("%(\\w+)%",getVar("$1"));
public String getVar(name){...return formatted;}
I have this line of code (In JAVA), and a function called getVar() that will give me the value of the variable with the name we want. The function is working perfectly, but this code doesn't seem to look for the groups anymore.
The String I am formatting with this regex is:
"My name is %name% and I am %age% years old."
And instead of giving me back: "My name is Paulo and I am 15 years old." (Because name = Paulo and age = 15) It gives me nothing back. Instead of replacing the regex with getVar(name) or getVar(age), it replaces it with getVar("$1").
Is there some way of fixing it, is this a bug, or intended behaviour? And if it is, how can I get the same result another way?
EDIT:
for(String i: varnames){
output = output.replaceAll("%"+i+"%",getVar(i));
}
Does the job for this specific case... But yet, is there a way to use functions inside of replaceAll() and maintaining the groups (e.g. $1, $2) working inside the function?
EDIT 2:
//Variables//
ArrayList<String> varnames = new ArrayList<String>(0);
ArrayList<String> varvalues = new ArrayList<String>(0);
//end of Variables
private String getVar(String name){
String returnv = "";
if(varnames.contains(name.toLowerCase())) returnv = varvalues.get(varnames.indexOf(name.toLowerCase()));
//System.out.println("\n\n"+name+"\n\n");
return returnv;
}
private String format(String input){
String output = input;
output = output.replace("[br]","/n");
for(String i: varnames){
output = output.replaceAll("%"+i+"%",getVar(i));//This is how I am parsing the variables.
}
//Here I want to handle inline functions... for example: a function called 'invert' that would switch the letters. If the input String that is being formatted (output) contains the regex, the function needs to evaluate and replace.
//How I tried to do it:
output.replaceAll("invert\((\w+)\)",invertLetters("$1"));
return output;
}
public String invertLetters(String input){//Inverts the letters of the String}
As mentioned by codisfy it is not clear at all if you are talking about java or javascript, as you use the replaceAll method I will consider that you use java. However what I will explain hereunder is valid for most (if not all) regex engines independently about the programming language.
When you call outputString=inputString.replaceAll("REGEX","REPLACEMENT"); the method replaceAll will configure its internal regex engine, build a finite automaton (for simplicity let's omit the difference between DFA/NFA here) with the regex passed as parameter and analyse the inputString on which it is called in order to do the replacement and return the result (outputString).
When the method is called it also needs a replacement String (REPLACEMENT) that is a normal string which may contain or not back-references to some groups, in order to enable some contextual replacement (using the syntax $1, $2 or \1, \2,... depending on the language).
What is very important to understand is that the regex as well as its replacement string are both just simple strings with no special meaning outside the regex engine (the method replaceAll).
Therefore, if you reuse them in other methods (for example by passing them as parameters) they will be interpreted literally as it is the case with other normal strings.
So do not expect that $1 is replaced by name or age in your call getVar("$1"). It will be just $1 and nothing else.
Also, this being said, your method public void getVar(name){...} does not even return a string since its return type is void, as consequence, if you code in java and if you use replaceAll method of String class (which expects 2 strings as arguments) it will NOT even compile in the first place.
I will let you implement the rest of the code but if you change your replacement loop in the following way it should work:
String input="My name is %name% and I am %age% years old.";
Matcher matcher = Pattern.compile("%(\\w+)%").matcher(input);
String output=new String(input);
while (matcher.find()) {
System.out.println("------------------------------------");
System.out.println("Back reference:" + matcher.group(1));
String group=matcher.group(1);//give access to the first matching group so that it can be reused
output=output.replaceAll("%"+group+"%", getVar(group));
}
System.out.println(output);
getVar method code: (I will let you adapt it)
public static String getVar(String name){
if(name.equals("name"))
return "Paulo";
return "15";
}
OUTPUT:
------------------------------------
Back reference:name
------------------------------------
Back reference:age
My name is Paulo and I am 15 years old.

Trim unwanted characters in a Java String

I have few Java Strings like below:
ab-android-regression-4.4-git
ab-ios-regression-4.4-git
ab-tablet-regression-4.4-git
However, I do not want such lengthy and unwanted names and so I want to get rid of starting ab- and ending -git part. The pattern for all the Strings is the same (starts with ab and ends with git)
Is there a function/class in Java that will help me in trimming such things? For example, something like:
String test = "ab-android-regression-4.4-git";
test.trim(ab, git)
Also, can StringUtils class help me with this? Thoughts on regular expressions?
EDITED PART: I also want to know how to eliminate the - characters in the Strings and change everything to uppercase letters
Here's a method that's more general purpose to remove a prefix and suffix from a string:
public static String trim (String str, String prefix, String suffix)
{
int indexOfLast = str.lastIndexOf(suffix);
// Note: you will want to do some error checking here
// in case the suffix does not occur in the passed in String
str = str.substring(0, indexOfLast);
return str.replaceFirst(prefix, "");
}
Usage:
String test = "ab-android-regression-4.4-git";
String trim = trim(test, "ab-", "-git"));
To remove the "-" and make uppercase, then just do:
trim = trim.replaceAll("-", " ").toUpperCase();
You can use test = test.replace("ab-", "") and similar for the "-git" or you can use test = StringUtils.removeStart(test, "ab-") and similarly, removeEnd.
I prefer the latter if you can use StringUtils because it won't ever accidentally remove the middle of the filename if those expressions are matched.
Since the parts to trim are constant in size, you should simply use substring :
yourString.substring(3, yourString.length - 4)
If your string always contains ab- at the begining and -git at the end then here is the code
String test = "ab-android-regression-4.4-git";
test=test.substring(3, s.length() - 4);
System.out.println("s is"+s); //output is android-regression-4.4
To know more about substrings click https://docs.oracle.com/javase/tutorial/java/data/manipstrings.html

match all characters in a string independent of their order in the sequence

I want to match certain group of characters in a String independent of their order in the String using regex fucntion. However, the only requirement is that they all must be there.
I have tried
String elD = "15672";
String t = "12";
if ((elD.matches(".*[" + t + "].*"))) {
System.out.println(elD);
}
This one checks whether any of the characters are present. But I want all of them to be there.
Also I tried
String elD = "15672";
String t = "12";
if ((elD.matches(".*(" + t + ").*"))) {
System.out.println(elD);
}
This does not work as well. I have searched quite a while but I could not find an example when all of the characters from the pattern must be present in the String independent of their order.
Thanks
You can write regex for this but it would not look nice. If you would want to check if your string contains anywhere x and y you would need to use few times look-ahead like
^(?=.*x)(?=.*y).*$
and use it like
yourStirng.matches(regex);
But this way you would need to create your own method which would generate you dynamic regex and add (?=.*X) for each character you want to check. You would also need to make sure that this character is not special in regex like ? or +.
Simpler and not less effective solution would be creating your own method which would check if your string contains all searched characters, something like
public static boolean containsUnordered(String input, String searchFor){
char[] characters = searchFor.toCharArray();
for (char c: characters)
if (!input.contains(String.valueOf(c)))
return false;
return true;
}
You can built a pattern from the search string using the replaceAll method:
String s = "12";
String pattern = s.replaceAll("(.)", "(?=[^$1]*$1)");
Note: You can't test the same character several times. (i.e. 112 gives (?=[^1]*1)(?=[^1]*1)(?=[^2]*2) that is exactly the same as (?=[^1]*1)(?=[^2]*2))
But in my opinion Pshemo method is probably more efficient.

why does this for loop wordcount method not work in java

Can anyone let me know why this wordsearch method doesn't work - the returned value of count is 0 everytime I run it.
public int wordcount(){
String spaceString = " ";
int count = 0;
for(int i = 0; i < this.getString().length(); i++){
if (this.getString().substring(i).equals(spaceString)){
count++;
}
}
return count;
}
The value of getString = my search string.
Much appreciated if anyone can help - I'm sure I'm prob doing something dumb.
Dylan
Read the docs:
The substring begins with the character at the specified index and extends to the end of this string.
Your if condition is only true once, if the last character of the string is a space. Perhaps you wanted charAt? (And even this won't properly handle double spaces; splitting on whitespace might be a better option.)
Because substring with only one argument returns the sub string starting from that index till the end of the string. So you're not comparing just one character.
Instead of substring define spaceString as a char, and use charAt(i)
this.getString().substring(i) -> this returns a sub string from the index i to the end of the String
So for example if your string was Test the above would return Test, est, st and finally t
For what you're trying to do there are alternative methods, but you could simple replace
this.getString().substring(i)
with
spaceString.equals(this.getString().charAt(i))
An alternative way of doing what you're trying to do is:
this.getString().split(spaceString)
This would return an array of Strings - the original string broken up by spaces.
Read the documentation of the method you are using:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int)
I.e. the count will be non zero only if you have a space on the end of your string
Using substring as you are will not work. If the value of getString() is "my search string" every iteration through the loop with have substring(i) return:
my search string
y search string
search string
search string
earch string
arch string
rch string
ch string
h string
string
string
tring
ring
ing
ng
g
Notice none of those equals " ".
Try using split.
public int countWords(String s){
return s.split("\\s+").length;
}
Change
if (this.getString().substring(i).equals(spaceString))
to
if (this.getString().charAt(i) == ' ')
this.getString().substring(i) returns a string from the index of (i) to the end of the string.
Example: for i=5, it will return "rown cow" from the string "the brown cow". This functionality isn't what you need.
If you pepper System.out.println() throughout your code (or use the debugger), you will see this.
I think it would be better to use something like String.split() or charAt(i).
By the way, even if you fix your code by counting spaces, it will not return the correct value for these conditions: "my dog" (word count=2) and "cow" (word count=1). There is also a problem if there are more than one space between words. ALso, this will produce a word cound of three:
" the cow ".

Split a String In Java against the split rule?

I have a string like this:
String str="\"myValue\".\"Folder\".\"FolderCentury\"";
Is it possible to split the above string by . but instead of getting three resulting strings only two like:
columnArray[0]= "myValue"."Folder";
columnArray[1]= "FolderCentury";
Or do I have to use an other java method to get it done?
Try this.
String s = "myValue.Folder.FolderCentury";
String[] a = s.split(java.util.regex.Pattern.quote("."));
Hi programmer/Yannish,
First of all the split(".") will not work and this will not return any result. I think java String split method not work for . delimiter, so please try java.util.regex.Pattern.quote(".") instead of split(".")
As I posted on the original Post (here), the next code:
String input = "myValue.Folder.FolderCentury";
String regex = "(?!(.+\\.))\\.";
String[] result=input.split(regex);
System.out.println("result: "+Arrays.toString(result));
Produces the required output (an array with two values):
result: [myValue.Folder, FolderCentury]
If the problem you're trying to solve is really that specific, you could do it even without using regular expression matches at all:
int lastDot = str.lastIndexOf(".");
columnArray[0] = str.substring(0, lastDot);
columnArray[1] = str.substring(lastDot + 1);

Categories

Resources