When I perform
String test="23x34 ";
String[] array=test.split("x"); //splitting using simple letter
I got two items in array as 23 and 34
but when I did
String test="23x34 ";
String[] array=test.split("X"); //splitting using capitalletter
I got one item in array 23x34
So is there any way I can use the split method as case insensitive or whether there is any other method that can help?
split uses, as the documentation suggests, a regexp. a regexp for your example would be :
"[xX]"
Also, the (?i) flag toggles case insensitivty. Therefore, the following is also correct :
"(?i)x"
In this case, x can be any litteral properly escaped.
Use regex pattern [xX] in split
String x = "24X45";
String[] res = x.split("[xX]");
System.out.println(Arrays.toString(res));
You can also use an embedded flag in your regex:
String[] array = test.split("(?i)x"); // splits case insensitive
I personally prefer using
String modified = Pattern.compile("x", Pattern.CASE_INSENSITIVE).matcher(stringContents).replaceAll(splitterValue);
String[] parts = modified.split(splitterValue);
In this way you can ensure any regex will work, as long as you have a unique splitter value
In addition to the existing answers, you can use Pattern.CASE_INSENSITIVE flag to convert your regex pattern into a case-insensitive pattern which you can directly use to split your string e.g.
String[] arr = Pattern.compile("x", Pattern.CASE_INSENSITIVE).split("23x34 ");
Demo:
import java.util.Arrays;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("x", Pattern.CASE_INSENSITIVE);
System.out.println(Arrays.toString(pattern.split("23x34 ")));
System.out.println(Arrays.toString(pattern.split("23X34 ")));
}
}
Output:
[23, 34 ]
[23, 34 ]
Java's String class' split method also accepts regex.
To keep things short, this should help you: http://www.coderanch.com/t/480781/java/java/String-split
For JavaScript:
var test="23x34 ";
var array = test.split(\x\i);
It's a bit complex, but here's how it could be implemented:
Lowercase both the strings (overall text and search term)
Run the text.split(searchTerm)
This gives you an array of strings that are NOT search terms
By walking through this array, you're getting lengths of each of these strings
Between each of those strings, there must be a search term (with known length)
By figuring out indexes, you can now .slice() the pieces from the original string
You could use a regex as an argument to split, like this:
"32x23".split("[xX]");
Or you could use a StringTokenizer that lets you set its set of delimiters, like this:
StringTokenizer st = new StringTokenizer("32x23","xX");
// ^^ ^^
// string delimiter
This has the advantage that if you want to build the list of delimiters programatically, for example for each lowercase letter in the delimiter list add its uppercase corespondent, you can do this and then pass the result to the StringTokenizer.
Related
I have a string = ab:cd:ef:gh. On this input, I want to return the string ef:gh (third colon intact).
The string apple:orange:cat:dog should return cat:dog (there's always 4 items and 3 colons).
I could have a loop that counts colons and makes a string of characters after the second colon, but I was wondering if there exists some easier way to solve it.
You can use the split() method for your string.
String example = "ab:cd:ef:gh";
String[] parts = example.split(":");
System.out.println(parts[parts.length-2] + ":" + parts[parts.length-1]);
String example = "ab:cd:ef:gh";
String[] parts = example.split(":",3); // create at most 3 Array entries
System.out.println(parts[2]);
The split function might be what you're looking for here. Use the colon, like in the documentation as your delimiter. You can then obtain the last two indexes, like in an array.
Yes, there is easier way.
First, is by using method split from String class:
String txt= "ab:cd:ef:gh";
String[] arr = example.split(":");
System.out.println(arr[arr.length-2] + " " + arr[arr.length-1]);
and the second, is to use Matcher class.
Use overloaded version of lastIndexOf(), which takes the starting index as 2nd parameter:
str.substring(a.lastIndexOf(":", a.lastIndexOf(":") - 1) + 1)
Another solution would be using a Pattern to match your input, something like [^:]+:[^:]+$. Using a pattern would probably be easier to maintain as you can easily change it to handle for example other separators, without changing the rest of the method.
Using a pattern is also likely be more efficient than String.split() as the latter is also converting its parameter to a Pattern internally, but it does more than what you actually need.
This would give something like this:
String example = "ab:cd:ef:gh";
Pattern regex = Pattern.compile("[^:]+:[^:]+$");
final Matcher matcher = regex.matcher(example);
if (matcher.find()) {
// extract the matching group, which is what we are looking for
System.out.println(matcher.group()); // prints ef:gh
} else {
// handle invalid input
System.out.println("no match");
}
Note that you would typically extract regex as a reusable constant to avoid compiling the pattern every time. Using a constant would also make the pattern easier to change without looking at the actual code.
I need to extract the desired string which attached to the word.
For example
pot-1_Sam
pot-22_Daniel
pot_444_Jack
pot_5434_Bill
I need to get the names from the above strings. i.e Sam, Daniel, Jack and Bill.
Thing is if I use substring the position keeps on changing due to the length of the number. How to achieve them using REGEX.
Update:
Some strings has 2 underscore options like
pot_US-1_Sam
pot_RUS_444_Jack
Assuming you have a standard set of above formats, It seems you need not to have any regex, you can try using lastIndexOf and substring methods.
String result = yourString.substring(yourString.lastIndexOf("_")+1, yourString.length());
Your answer is:
String[] s = new String[4];
s[0] = "pot-1_Sam";
s[1] = "pot-22_Daniel";
s[2] = "pot_444_Jack";
s[3] = "pot_5434_Bill";
ArrayList<String> result = new ArrayList<String>();
for (String value : s) {
String[] splitedArray = value.split("_");
result.add(splitedArray[splitedArray.length-1]);
}
for(String resultingValue : result){
System.out.println(resultingValue);
}
You have 2 options:
Keep using the indexOf method to get the index of the last _ (This assumes that there is no _ in the names you are after). Once that you have the last index of the _ character, you can use the substring method to get the bit you are after.
Use a regular expression. The strings you have shown essentially have the pattern where in you have numbers, followed by an underscore which is in turn followed by the word you are after. You can use a regular expression such as \\d+_ (which will match one or more digits followed by an underscore) in combination with the split method. The string you are after will be in the last array position.
Use a string tokenizer based on '_' and get the last element. No need for REGEX.
Or use the split method on the string object like so :
String[] strArray = strValue.split("_");
String lastToken = strArray[strArray.length -1];
String[] s = {
"pot-1_Sam",
"pot-22_Daniel",
"pot_444_Jack",
"pot_5434_Bill"
};
for (String e : s)
System.out.println(e.replaceAll(".*_", ""));
Problem description
I am trying to split a into separate strings, with the split() method that the String class provides. The documentation tells me that it will split around matches of the argument, which is a regular expression. The delimiter that I use is a comma, but commas can also be escaped. Escaping character that I use is a forward slash / (just to make things easier by not using a backslash, because that requires additional escaping in string literals in both Java and the regular expressions).
For instance, the input might be this:
a,b/,b//,c///,//,d///,
And the output should be:
a
b,b/
c/,/
d/,
So, the string should be split at each comma, unless that comma is preceded by an odd number of slashes (1, 3, 5, 7, ..., ∞) because that would mean that the comma is escaped.
Possible solutions
My initial guess would be to split it like this:
String[] strings = longString.split("(?<![^/](//)*/),");
but that is not allowed because Java doesn't allow infinite look-behind groups. I could limit the recurrence to, say, 2000 by replacing the * with {0,2000}:
String[] strings = longString.split("(?<![^/](//){0,2000}/),");
but that still puts constraints on the input. So I decided to take the recurrence out of the look-behind group, and came up with this:
String[] strings = longString.split("(?<!/)(?:(//)*),");
However, its output is the following list of strings:
a
b,b (the final slash is lacking in the output)
c/, (the final slash is lacking in the output)
d/,
Why are those slashes omitted in the 2nd and 3rd string, and how can I solve it (in Java)?
You are pretty close. To overcome lookbehind error you can use this workaround:
String[] strings = longString.split("(?<![^/](//){0,99}/),")
You can achieve the split using a positive look behind for an even number of slashes preceding the comma:
String[] strings = longString.split("(?<=[^/](//){0,999999999}),");
But to display the output you want, you need a further step of removing the remaining escapes:
String longString = "a,b/,b//,c///,//,d///,";
String[] strings = longString.split("(?<=[^/](//){0,999999999}),");
for (String s : strings)
System.out.println(s.replaceAll("/(.)", "$1"));
Output:
a
b,b/
c/,/
d/,
If you don't mind another method with regex, I suggest using .matcher:
Pattern pattern = Pattern.compile("(?:[^,/]+|/.)+");
String test = "a,b/,b//,c///,//,d///,";
Matcher matcher = pattern.matcher(test);
while (matcher.find()) {
System.out.println(matcher.group().replaceAll("/(.)", "$1"));
}
Output:
a
b,b/
c/,/
d/,
ideone demo
This method will match everything except the delimiting commas (kind of the reverse). The advantage is that it doesn't rely on lookarounds.
I love regexes, but wouldn't it be easy to write the code manually here, i.e.
boolean escaped = false;
for(int i = 0, len = s.length() ; i < len ; i++){
switch(s.charAt(i)){
case "/": escaped = !escaped; break;
case ",":
if(!escaped){
//found a segment, do something with it
}
//Fallthrough!
default:
escaped = false;
}
}
// handle last segment
I have a string in what is the best way to put the things in between $ inside a list in java?
String temp = $abc$and$xyz$;
how can i get all the variables within $ sign as a list in java
[abc, xyz]
i can do using stringtokenizer but want to avoid using it if possible.
thx
Maybe you could think about calling String.split(String regex) ...
The pattern is simple enough that String.split should work here, but in the more general case, one alternative for StringTokenizer is the much more powerful java.util.Scanner.
String text = "$abc$and$xyz$";
Scanner sc = new Scanner(text);
while (sc.findInLine("\\$([^$]*)\\$") != null) {
System.out.println(sc.match().group(1));
} // abc, xyz
The pattern to find is:
\$([^$]*)\$
\_____/ i.e. literal $, a sequence of anything but $ (captured in group 1)
1 and another literal $
The […] is a character class. Something like [aeiou] matches one of any of the lowercase vowels. [^…] is a negated character class. [^aeiou] matches one of anything but the lowercase vowels.
(…) is used for grouping. (pattern) is a capturing group and creates a backreference.
The backslash preceding the $ (outside of character class definition) is used to escape the $, which has a special meaning as the end of line anchor. That backslash is doubled in a String literal: "\\" is a String of length one containing a backslash).
This is not a typical usage of Scanner (usually the delimiter pattern is set, and tokens are extracted using next), but it does show how'd you use findInLine to find an arbitrary pattern (ignoring delimiters), and then using match() to access the MatchResult, from which you can get individual group captures.
You can also use this Pattern in a Matcher find() loop directly.
Matcher m = Pattern.compile("\\$([^$]*)\\$").matcher(text);
while (m.find()) {
System.out.println(m.group(1));
} // abc, xyz
Related questions
Validating input using java.util.Scanner
Scanner vs. StringTokenizer vs. String.Split
Just try this one:temp.split("\\$");
I would go for a regex myself, like Riduidel said.
This special case is, however, simple enough that you can just treat the String as a character sequence, and iterate over it char by char, and detect the $ sign. And so grab the strings yourself.
On a side node, I would try to go for different demarkation characters, to make it more readable to humans. Use $ as start-of-sequence and something else as end-of-sequence for instance. Or something like I think the Bash shell uses: ${some_value}. As said, the computer doesn't care but you debugging your string just might :)
As for an appropriate regex, something like (\\$.*\\$)* or so should do. Though I'm no expert on regexes (see http://www.regular-expressions.info for nice info on regexes).
Basically I'd ditto Khotyn as the easiest solution. I see you post on his answer that you don't want zero-length tokens at beginning and end.
That brings up the question: What happens if the string does not begin and end with $'s? Is that an error, or are they optional?
If it's an error, then just start with:
if (!text.startsWith("$") || !text.endsWith("$"))
return "Missing $'s"; // or whatever you do on error
If that passes, fall into the split.
If the $'s are optional, I'd just strip them out before splitting. i.e.:
if (text.startsWith("$"))
text=text.substring(1);
if (text.endsWith("$"))
text=text.substring(0,text.length()-1);
Then do the split.
Sure, you could make more sophisticated regex's or use StringTokenizer or no doubt come up with dozens of other complicated solutions. But why bother? When there's a simple solution, use it.
PS There's also the question of what result you want to see if there are two $'s in a row, e.g. "$foo$$bar$". Should that give ["foo","bar"], or ["foo","","bar"] ? Khotyn's split will give the second result, with zero-length strings. If you want the first result, you should split("\$+").
If you want a simple split function then use Apache Commons Lang which has StringUtils.split. The java one uses a regex which can be overkill/confusing.
You can do it in simple manner writing your own code.
Just use the following code and it will do the job for you
import java.util.ArrayList;
import java.util.List;
public class MyStringTokenizer {
/**
* #param args
*/
public static void main(String[] args) {
List <String> result = getTokenizedStringsList("$abc$efg$hij$");
for(String token : result)
{
System.out.println(token);
}
}
private static List<String> getTokenizedStringsList(String string) {
List <String> tokenList = new ArrayList <String> ();
char [] in = string.toCharArray();
StringBuilder myBuilder = null;
int stringLength = in.length;
int start = -1;
int end = -1;
{
for(int i=0; i<stringLength;)
{
myBuilder = new StringBuilder();
while(i<stringLength && in[i] != '$')
i++;
i++;
while((i)<stringLength && in[i] != '$')
{
myBuilder.append(in[i]);
i++;
}
tokenList.add(myBuilder.toString());
}
}
return tokenList;
}
}
You can use
String temp = $abc$and$xyz$;
String array[]=temp.split(Pattern.quote("$"));
List<String> list=new ArrayList<String>();
for(int i=0;i<array.length;i++){
list.add(array[i]);
}
Now the list has what you want.
As per my project I need to devide a string into two parts.
below is the example:
String searchFilter = "(first=sam*)(last=joy*)";
Where searchFilter is a string.
I want to split above string to two parts
first=sam* and last=joy*
so that i can again split this variables into first,sam*,last and joy* as per my requirement.
I dont have much hands on experience in java. Can anyone help me to achieve this one. It will be very helpfull.
Thanks in advance
The most flexible way is probably to do it with regular expressions:
import java.util.regex.*;
public class Test {
public static void main(String[] args) {
// Create a regular expression pattern
Pattern spec = Pattern.compile("\\((.*?)=(.*?)\\)");
// Get a matcher for the searchFilter
String searchFilter = "(first=sam*)(last=joy*)";
Matcher m = spec.matcher(searchFilter);
// While a "abc=xyz" pattern can be found...
while (m.find())
// ...print "abc" equals "xyz"
System.out.println("\""+m.group(1)+"\" equals \""+m.group(2)+"\"");
}
}
Output:
"first" equals "sam*"
"last" equals "joy*"
Take a look at String.split(..) and String.substring(..), using them you should be able to achieve what you are looking for.
you can do this using split or substring or using StringTokenizer.
I have a small code that will solve ur problem
StringTokenizer st = new StringTokenizer(searchFilter, "(||)||=");
while(st.hasMoreTokens()){
System.out.println(st.nextToken());
}
It will give the result you want.
I think you can do it in a lot of different ways, it depends on you.
Using regexp or what else look at https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html.
Anyway I suggest:
int separatorIndex = searchFilter.indexOf(")(");
String filterFirst = searchFilter.substring(1,separatorIndex);
String filterLast = searchFilter.substring(separatorIndex+1,searchFilter.length-1);
This (untested snippet) could do it:
String[] properties = searchFilter.replaceAll("(", "").split("\)");
for (String property:properties) {
if (!property.equals("")) {
String[] parts = property.split("=");
// some method to store the filter properties
storeKeyValue(parts[0], parts[1]);
}
}
The idea behind: First we get rid of the brackets, replacing the opening brackets and using the closing brackets as a split point for the filter properties. The resulting array includes the String {"first=sam*","last=joy*",""} (the empty String is a guess - can't test it here). Then for each property we split again on "=" to get the key/value pairs.