For example I have this string params: Blabla,1,Yooooooo,Stackoverflow,foo,chinese
And I want to get the string testCaseParams until the 3rd comma: Blabla,1,Yooooooo
and then remove it and the comma from the original string so I get thisStackoverflow,foo,chinese
I'm trying this code but testCaseParams only shows the first two values (gets index of the 2nd comma, not 3rd...)
//Get how many parameters this test case has and group the parameters
int amountOfInputs = 3;
int index = params.indexOf(',', params.indexOf(',') + amountOfInputs);
String testCaseParams = params.substring(0,index);
params = params.replace(testCaseParams + ",","");
You can hold the index of the currently-found comma in a variable and iterate until the third comma is found:
int index = 0;
for (int i=0; i<3; i++) index = str.indexOf(',', index);
String left = str.substring(0, index);
String right = str.substring(index+1); // skip comma
Edit: to validate the string, simply check if index == -1. If so, there are not 3 commas in the string.
One option would be a clever use of String#split:
String input = "Blabla,1,Yooooooo,Stackoverflow,foo,chinese";
String[] parts = input.split("(?=,)");
String output = parts[0] + parts[1] + parts[2];
System.out.println(output);
Demo
One can use split with a limit of 4.
String input = "Blabla,1,Yooooooo,Stackoverflow,foo,chinese";
String[] parts = input.split(",", 4);
if (parts.length == 4) {
String first = parts[0] + "," + parts[1] + "," + parts[2];
String second = parts[3]; // "Stackoverflow,foo,chinese"
}
You can split with this regex to get the 2 pats:
String[] parts = input.split("(?<=\\G.*,.*,.*),");
It will result in parts equal to:
{ "Blabla,1,Yooooooo", "Stackoverflow,foo,chinese" }
\\G refers to the previous match or the start of the string.
(?<=) is positive look-behind.
So it means match a comma for splitting, if it is preceded by 2 other commas since the previous match or the start of the string.
This will keep empty strings between commas.
I offer this here just as a "fun" one line solution:
public static int nthIndexOf(String str, String c, int n) {
return str.length() - str.replace(c, "").length() < n ? -1 : n == 1 ? str.indexOf(c) : c.length() + str.indexOf(c) + nthIndexOf(str.substring(str.indexOf(c) + c.length()), c, n - 1);
}
//Usage
System.out.println(nthIndexOf("Blabla,1,Yooooooo,Stackoverflow,foo,chinese", ",", 3)); //17
(It's recursive of course, so will blow up on large strings, it's relatively slow, and certainly isn't a sensible way to do this in production.)
As a more sensbile one liner using a library, you can use Apache commons ordinalIndexOf(), which achieves the same thing in a more sensible way!
Related
There is a way to split a string into repeating characters using a regex function but I want to do it without using it.
for example, given a string like: "EE B" my output will be an array of strings e.g
{"EE", " ", "B"}
my approach is:
given a string I will first find the number of unique characters in a string so I know the size of the array. Then I will change the string to an array of characters. Then I will check if the next character is the same or not. if it is the same then append them together if not begin a new string.
my code so far..
String myinput = "EE B";
char[] cinput = new char[myinput.length()];
cinput = myinput.toCharArray(); //turn string to array of characters
int uniquecha = myinput.length();
for (int i = 0; i < cinput.length; i++) {
if (i != myinput.indexOf(cinput[i])) {
uniquecha--;
} //this should give me the number of unique characters
String[] returninput = new String[uniquecha];
Arrays.fill(returninput, "");
for (int i = 0; i < uniquecha; i++) {
returninput[i] = "" + myinput.charAt(i);
for (int j = 0; j < myinput.length - 1; j++) {
if (myinput.charAt(j) == myinput.charAt(j + 1)) {
returninput[j] += myinput.charAt(j + 1);
} else {
break;
}
}
} return returninput;
but there is something wrong with the second part as I cant figure out why it is not beginning a new string when the character changes.
You question says that you don't want to use regex, but I see no reason for that requirement, other than this is maybe homework. If you are open to using regex here, then there is a one line solution which splits your input string on the following pattern:
(?<=\S)(?=\s)|(?<=\s)(?=\S)
This pattern uses lookarounds to split whenever what precedes is a non whitespace character and what proceeds is a whitespace character, or vice-versa.
String input = "EE B";
String[] parts = input.split("(?<=\\S)(?=\\s)|(?<=\\s)(?=\\S)");
System.out.println(Arrays.toString(parts));
[EE, , B]
^^ a single space character in the middle
Demo
If I understood correctly, you want to split the characters in a string so that similar-consecutive characters stay together. If that's the case, here is how I would do it:
public static ArrayList<String> splitString(String str)
{
ArrayList<String> output = new ArrayList<>();
String combo = "";
//iterates through all the characters in the input
for(char c: str.toCharArray()) {
//check if the current char is equal to the last added char
if(combo.length() > 0 && c != combo.charAt(combo.length() - 1)) {
output.add(combo);
combo = "";
}
combo += c;
}
output.add(combo); //adds the last character
return output;
}
Note that instead of using an array (has a fixed size) to store the output, I used an ArrayList, which has a variable size. Also, instead of checking the next character for equality with the current one, I preferred to use the last character for that. The variable combo is used to temporarily store the characters before they go to output.
Now, here is one way to print the result following your guidelines:
public static void main(String[] args)
{
String input = "EEEE BCD DdA";
ArrayList<String> output = splitString(input);
System.out.print("[");
for(int i = 0; i < output.size(); i++) {
System.out.print("\"" + output.get(i) + "\"");
if(i != output.size()-1)
System.out.print(", ");
}
System.out.println("]");
}
The output when running the above code will be:
["EEEE", " ", "B", "C", "D", " ", "D", "d", "A"]
I want to select the first N words of a text string.
I have tried split() and substring() to no avail.
What I want is to select the first 3 words of the following prayer and copy them to another variable.
For example if I have a string:
String greeting = "Hello this is just an example"
I want to get into the variable Z the first 3 words so that
Z = "Hello this is"
String myString = "Copying first N numbers of words to a string";
String [] arr = myString.split("\\s+");
//Splits words & assign to the arr[] ex : arr[0] -> Copying ,arr[1] -> first
int N=3; // NUMBER OF WORDS THAT YOU NEED
String nWords="";
// concatenating number of words that you required
for(int i=0; i<N ; i++){
nWords = nWords + " " + arr[i] ;
}
System.out.println(nWords);
NOTE : Here .split() function returns an array of strings computed by splitting a given string around matches of the given regular expression
so if i write the code like follows
String myString = "1234M567M98723651";
String[] arr = myString.split("M"); //idea : split the words if 'M' presents
then answers will be : 1234 and 567 where stored into an array.
This is doing by storing the split values into the given array. first split value store to arr[0], second goes to arr[1].
Later part of the code is for concatenating the required number of split words
Hope that you can get an idea from this!!!
Thank you!
public String getFirstNStrings(String str, int n) {
String[] sArr = str.split(" ");
String firstStrs = "";
for(int i = 0; i < n; i++)
firstStrs += sArr[i] + " ";
return firstStrs.trim();
}
Now getFirstNStrings("Hello this is just an example", 3); will output:
Hello this is
You could try something like:
String greeting = "Hello this is just an example";
int end = 0;
for (int i=0; i<3; i++) {
end = greeting.indexOf(' ', end) + 1;
}
String Z = greeting.substring(0, end - 1);
N.B. This assumes there are at least three space characters in your source string. Any less and this code will probably fail.
Add this in a utility class, such as Util.java
public static String getFirstNWords(String s, int n) {
if (s == null) return null;
String [] sArr = s.split("\\s+");
if (n >= sArr.length)
return s;
String firstN = "";
for (int i=0; i<n-1; i++) {
firstN += sArr[i] + " ";
}
firstN += sArr[n-1];
return firstN;
}
Usage:
Util.getFirstNWords("This will give you the first N words", 3);
---->
"This will give"
If you use Apache Commons Lang3, you can make it a little shorter like this:
public String firstNWords(String input, int numOfWords) {
String[] tokens = input.split(" ");
tokens = ArrayUtils.subarray(tokens, 0, numOfWords);
return StringUtils.join(tokens, ' ');
}
Most of the answers posted already use regular expressions which can become an overhead if we have to process a large number of strings. Even str.split(" ") uses regular expression operations internally. dave's answer is perhaps the mos efficient, but it does not handle correctly strings that have multiple spaces occurring together, beside assuming that regular space is the only word separator and that the input string has 3 or more words (an assumption he has already called out). If using Apache Commons in an option, then I would use the following code as it is not only concise and avoids using regular expression even internally but also handled gracefully input strings that have less than 3 words:
/* Splits by whitespace characters. All characters after the 3rd whitespace,
* if present in the input string, go into the 4th "word", which could really
* be a concanetation of multiple words. For the example in the question, the
* 4th "word" in the result array would be "just an example". Invoking the
* utility method with max-splits specified is slightly more efficient as it
* avoids the need to look for and split by space after the first 3 words have
* been extracted
*/
String[] words = StringUtils.split(greeting, null, 4);
String Z = StringUtils.join((String[]) ArrayUtils.subarray(words, 0, 3), ' ');
I am trying to figure out that -
INPUT: String data = "506313B5EA3E";
OUTPUT: String data = "50:63:13:B5:EA:3E";
I tried using-
java.util.Arrays.toString(data.split("(?<=\\G..)"))
But the output is: [50, 6313B5EA3E]
You can use a RegExp:
String input = "0123456789abcdef";
String output = input.replaceAll("..(?!$)", "$0:")
// output = "01:23:45:67:89:ab:cd:ef"
How does it work?
.. matches exactly two characters. (?!$) ensures that these two characters are not at the end of input (?! is a negative lookahead, $ stands for the end).
The matching two characters will now be replaced by themselves ($0 means the whole matching string) and the colon we want.
Since we are using replaceALL, this operation repeats for every two-character group. Remember: except the last one.
Two simple options involving loops, both assuming you have already checked that the input is non-empty and has an even number of characters:
Use StringBuilder
StringBuilder builder = new StringBuilder(data.length() * 3 / 2 - 1);
for (int i = 0; i < data.length(); i += 2) {
if (i != 0) {
builder.append(":");
}
builder.append(data.substring(i, i + 2));
}
String text = builder.toString();
Use a char array
char[] output = new char[data.length() * 3 / 2 - 1];
int outputIndex = 0;
for (int i = 0; i < data.length(); i += 2) {
if (i != 0) {
output[outputIndex++] = ':';
}
output[outputIndex++] = data.charAt(i);
output[outputIndex++] = data.charAt(i + 1);
}
String text = new String(output);
Another option would be to use Joiner from Guava along with your previous split:
String text = Joiner.on(':').join(data.split("(?<=\\G..)"));
How would I replace a string 10100 with 10010 using the algorithm "replace the last substring 10 with 01."
I tried
s=s.replace(s.substring(a,a+2), "01");
but this returns 01010, replacing both the first and the second substring of "10".
"a" represents s.lastindexOf("10");
Here's a simple and extensible function you can use. First its use/output and then its code.
String original = "10100";
String toFind = "10";
String toReplace = "01";
int ocurrence = 2;
String replaced = replaceNthOcurrence(original, toFind, toReplace, ocurrence);
System.out.println(replaced); // Output: "10010"
original = "This and This and This";
toFind = "This";
toReplace = "That";
ocurrence = 3;
replaced = replaceNthOcurrence(original, toFind, toReplace, ocurrence);
System.out.println(replaced); // Output: "This and This and That"
Function code:
public static String replaceNthOcurrence(String str, String toFind, String toReplace, int ocurrence) {
Pattern p = Pattern.compile(Pattern.quote(toFind));
Matcher m = p.matcher(str);
StringBuffer sb = new StringBuffer(str);
int i = 0;
while (m.find()) {
if (++i == ocurrence) { sb.replace(m.start(), m.end(), toReplace); break; }
}
return sb.toString();
}
If you want to access the last two indices of a string, then you can use: -
str.substring(str.length() - 2);
This gives you string from index str.length() - 2 to the last character, which is exactly the last two character.
Now, you can replace the last two indices with whatever string you want.
UPDATE: -
Of you want to access the last occurrence of a character or substring, you can use String#lastIndexOf method: -
str.lastIndexOf("10");
Ok, you can try this code: -
String str = "10100";
int fromIndex = str.lastIndexOf("10");
str = str.substring(0, fromIndex) + "01" + str.substring(fromIndex + 2);
System.out.println(str);
10100 with 10010
String result = "10100".substring(0, 2) + "10010".substring(2, 4) + "10100".substring(4, 5);
You can get the last index of a character or substring using string's lastIndexOf method. See the documentation link below for how to use it.
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#lastIndexOf(java.lang.String)
Once you know the index of your substring, you can get the substring of all characters before that index, and the substring of all characters after the last character in your search string, and concatenate.
This is a little drawn out, and I didn't actually run it (so I might have a syntax error), but it gives you the point of what I'm trying to convey at least. You could do this all in one line if you want, but it wouldn't illustrate the point as well.
string s = "10100";
string searchString = "10";
string replacementString = "01";
string charsBeforeSearchString = s.substring(0, s.lastIndexOf(searchString) - 1);
string charsAfterSearchString = s.substring(s.lastIndexIf(searchString) + 2);
s = charsBeforeSearchString + replacementString + charsAfterSearchString;
The easiest way:
String input = "10100";
String result = Pattern.compile("(10)(?!.*10.*)").matcher(input).replaceAll("01");
System.out.println(result);
I have a string that I need to be split into 2. I want to do this by splitting at exactly the third comma.
How do I do this?
Edit
A sample string is :
from:09/26/2011,type:all,to:09/26/2011,field1:emp_id,option1:=,text:1234
The string will keep the same format - I want everything before field in a string.
If you're simply interested in splitting the string at the index of the third comma, I'd probably do something like this:
String s = "from:09/26/2011,type:all,to:09/26/2011,field1:emp_id,option1:=,text:1234";
int i = s.indexOf(',', 1 + s.indexOf(',', 1 + s.indexOf(',')));
String firstPart = s.substring(0, i);
String secondPart = s.substring(i+1);
System.out.println(firstPart);
System.out.println(secondPart);
Output:
from:09/26/2011,type:all,to:09/26/2011
field1:emp_id,option1:=,text:1234
Related question:
How to find nth occurrence of character in a string?
a naive implementation
public static String[] split(String s)
{
int index = 0;
for(int i = 0; i < 3; i++)
index = s.indexOf(",", index+1);
return new String[] {
s.substring(0, index),
s.substring(index+1)
};
}
This does no bounds checking and will throw all sorts of lovely exceptions if not given input as expected. Given "ABCD,EFG,HIJK,LMNOP,QRSTU" returns ["ABCD,EFG,HIJK","LMNOP,QRSTU"]
You can use this regex:
^([^,]*,[^,]*,[^,]*),(.*)$
The result is then in the two captures (1 and 2), not including the third comma.