How to Split a String based on the nth(Ex: second) occurence of a delimiter.whereas other than the nth occurence ,all other delimiters should be retained
I/P:
String name="This is my First Line";
int delimiter=" ";
int count=3;//This is a dynamic value
O/P:
String firstpart=This is my
String Secondpart=First Line
Due to limitations with regex, you can't split it in 1 line of code, but you can do it in 2 lines:
String firstPart = name.replaceAll("^((.*?" + delimiter + "){" + count + "}).*", "$1");
String secondPart = name.replaceAll("^(.*?" + delimiter + "){" + count + "}(.*)", "$2");
I got it like this
String name="This is my First Line";
int count=3;
String s1,s2;
String arr[]=name.split();//default will be space
for(i=0;i<arr.length;i++)
if(i<count)
s1=s1+arr[i]+" "
else
s2=s2+arr[i]+" "
Just use indexOf to search for the delimiter and repeat that until you found it count-times. Here is a snippet:
String name = "This is my First Line";
String delimiter = " ";
int count = 3;
// Repeativly search for the delimiter
int lastIndex = -1;
for (int i = 0; i < count; i++) {
// Begin to search from the position after the last matching index
lastIndex = name.indexOf(delimiter, lastIndex + 1);
// Could not be found
if (lastIndex == -1) {
break;
}
}
// Get the result
if (lastIndex == -1) {
System.out.println("Not found!");
} else {
// Use the index to split
String before = name.substring(0, lastIndex);
String after = name.substring(lastIndex);
// Print the results
System.out.println(before);
System.out.println(after);
}
It will now output
This is my
First Line
Note the whitespace (the delimiter) at the beginning of the last line, you can omit this if you want by using the following code at the end
// Remove the delimiter from the beginning of 'after'
String after = ...
after = after.subString(delimiter.length());
static class FindNthOccurrence
{
String delimiter;
public FindNthOccurrence(String del)
{
this.delimiter = del;
}
public int findAfter(String findIn, int findOccurence)
{
int findIndex = 0;
for (int i = 0; i < findOccurence; i++)
{
findIndex = findIn.indexOf(delimiter, findIndex);
if (findIndex == -1)
{
return -1;
}
}
return findIndex;
}
}
FindNthOccurrence nth = new FindNthOccurrence(" ");
String string = "This is my First Line";
int index = nth.nthOccurrence(string, 2);
String firstPart = string.substring(0, index);
String secondPart = string.substring(index+1);
Simply like this,
Tested and work perfectly in Java 8
public String[] split(String input,int at){
String[] out = new String[2];
String p = String.format("((?:[^/]*/){%s}[^/]*)/(.*)",at);
Pattern pat = Pattern.compile(p);
Matcher matcher = pat.matcher(input);
if (matcher.matches()) {
out[0] = matcher.group(1);// left
out[1] = matcher.group(2);// right
}
return out;
}
//Ex: D:/folder1/folder2/folder3/file1.txt
//if at = 2, group(1) = D:/folder1/folder2 and group(2) = folder3/file1.txt
Related
I want the find the first vowel in a string (apellidoPat) for example if my string it's "CRUZ" my expexted output is : "U" to concatenate in rfc what can I use ? a loop ??
rfc : first letter of apellidoPat + first vowel of apellidoPat + irst letter of apellidoMat + date (YYMMDD)
I have all except first vowel of apellidoPat
private String getRFC() {
String rfc = "";
String apellidoPat = "CRUZ";
String apellidoMat = "HERNANDEZ";
String nombre = "JAVIER";
String fechaNac = "1997-12-25";
rfc = apellidoPat.substring(0,1) + "FIST VOWEL apellidoPat" + apellidoMat.substring(0,1) + nombre.substring(0,1) + fechaNac.substring(2,4) + fechaNac.substring(5,7) + fechaNac.substring(8,10);
// Expected output: CUHJ971225
return rfc
}
You do not need to add the date part by part to avoid -, it is better to split it by - and join the parts together to get desired result. And you can use a loop to find first vowel:
private String getRFC(){
String vowels = "AEIOUaeiou";
String apellidoPat = "CRUZ";
String apellidoMat = "HERNANDEZ";
String fechaNac = "1997-12-25";
// first letter of apellidoPat
String rfc = String.valueOf(apellidoPat.charAt(0));
// first vowel of apellidoPat
for (int i = 0; i < apellidoPat.length(); ++i){
if (vowels.indexOf(apellidoPat.charAt(i)) != -1){
rfc += String.valueOf(apellidoPat.charAt(i));
break;
}
}
// first letter of apellidoMat + date (YYMMDD)
rfc += apellidoMat.charAt(0) + String.join("", fechaNac.split("-"));
return rfc;
}
To get the first vowel of a string, you can try:
static final String vowels = "aeiou";
int indexOfFirstVowel = indexOfFirstVowel(apellidoPat);
private static int indexOfFirstVowel(String word){
String loweredWord = word.toLowerCase();
for (int index=0; index<loweredWord.length(); index++)
{
if (vowels.contains(String.valueOf(loweredWord.charAt(index))))
{
return index;
}
}
return -1;
}
Explanation:
indexOfFirstVowel method return the index of the first vowel in case it is found. Otherwise, it will return -1. You can change as per your requirement.
In case of String apellidoPat = "CRUZ"; this method return 2 i.e. index of U.
You can try below code.
String rfc;
String apellidoPat = "CRUZ";
int indexOfFirstVowel = indexOfFirstVowel(apellidoPat);
String apellidoMat = "HERNANDEZ";
String nombre = "JAVIER";
String fechaNac = "1997-12-25";
rfc = apellidoPat.substring(0, 1);
if(indexOfFirstVowel != -1) {
rfc += apellidoPat.charAt(indexOfFirstVowel);
}
rfc += apellidoMat.substring(0,1) + nombre.substring(0,1) + fechaNac.substring(2,4) + fechaNac.substring(5,7) + fechaNac.substring(8,10);
System.out.println(rfc);
Find first vowel from string and add it to a var
You can do it by replacing all characters except the vowels with an empty string and get the first character from the replaced string.
public class Main {
public static void main(String[] args) {
String apellidoPat = "CRUZ";
String replacedStr = apellidoPat.replaceAll("[^AEIOUaeiou]", "");
String firstVowel = "";
if (!replacedStr.isEmpty()) {
firstVowel = replacedStr.substring(0, 1);
}
System.out.println(firstVowel);
}
}
Output:
U
Thus, in your case, it will be:
rfc = firstVowel + "FIST VOWEL apellidoPat" + apellidoMat.substring(0,1) + nombre.substring(0,1) + fechaNac.substring(2,4) + fechaNac.substring(5,7) + fechaNac.substring(8,10);
Note: Check this for the explanation of the regex I have used with String#replaceAll.
you can use a for loop for this intention. for example :
String text = "CRUZ";
String vawel = "aeiouAEIOU";
for(int i=0 ; i<text.length() ; i++)
{
char ch = text.charAt(i);
if(vawel.contains(String.valueOf(ch)))
{
//add to your variable
}
}
I have written following code to get next word from a string in Java. I feel its very raw and I shouldn't have to write so much code for this but couldn't find any other way. Want to know if there are better ways available to do same:
public static String getNextWord(String str, String word) {
String nextWord = null;
// to remove multi spaces with single space
str = str.trim().replaceAll(" +", " ");
int totalLength = str.length();
int wordStartIndex = str.indexOf(word);
if (wordStartIndex != -1) {
int startPos = wordStartIndex + word.length() + 1;
if (startPos < totalLength) {
int nextSpaceIndex = str.substring(startPos).indexOf(" ");
int endPos = 0;
if (nextSpaceIndex == -1) {
// we've reached end of string, no more space left
endPos = totalLength;
} else {
endPos = startPos + nextSpaceIndex;
}
nextWord = str.substring(startPos, endPos);
}
}
return nextWord;
}
Note: the input word could be anything (multi words, single word, a word not in string etc).
Test:
String text = "I am very happy with life";
System.out.println(StringUtil.getNextWord(text, "I"));
System.out.println(StringUtil.getNextWord(text, "I am"));
System.out.println(StringUtil.getNextWord(text, "life"));
System.out.println(StringUtil.getNextWord(text, "with"));
System.out.println(StringUtil.getNextWord(text, "fdasfasf"));
System.out.println(StringUtil.getNextWord(text, text));
Output:
am
very
null
life
null
null
This sounds like a job for regex. Something like this:
public static String getNextWord(String str, String word){
Pattern p = Pattern.compile(word+"\\W+(\\w+)");
Matcher m = p.matcher(str);
return m.find()? m.group(1):null;
}
Hope this will serve your purpose.
public static String getNextWord(String str, String word) {
String[] words = str.split(" "), data = word.split(" ");
int index = Arrays.asList(words).indexOf((data.length > 1) ? data[data.length - 1] : data[0]);
return (index == -1) ? "Not Found" : ((index + 1) == words.length) ? "End" : words[index + 1];
}
Input (single word) :
String str = "Auto generated method stub";
String word = "method";
Out Put:
next word: stub
Input (multi-words) :
String str = "Auto generated method stub";
String word = "Auto generated";
Out Put:
next word: method
Input (missing word) :
String str = "Auto generated method stub";
String word = "was";
Out Put:
next word: Not Found
Input (end word) :
String str = "Auto generated method stub";
String word = "stub";
Out Put:
next word: End
You can create an array of words by doing this:
String[] words = str.split(" ");
This splits the string into strings when separated by a space. Note you keep needing to trim the str as you want to.
Now, you can somehow search in the array by finding some word and adding 1 to the index to get the next one.
nextword = words[words.indexOf(word) + 1];
I think, this solution works correctly:
public static String getNextWord(String str, String word) {
String[] strArr = str.split(word);
if(strArr.length > 1) {
strArr = strArr[1].trim().split(" ");
return strArr[0];
}
return null;
}
You can try the below code.
public static String getNextWord(String str, String word) {
try {
List<String> text = Arrays.asList(str.split(" "));
List<String> list = Arrays.asList(word.split(" "));
int index_of = text.indexOf(list.get(list.size() - 1));
return (index_of == -1) ? null : text.get(index_of + 1);
} catch(Exception e) {
return null;
}
}
Hope this is what you are looking for:
public static void main(String[] args) {
String text = "I am very happy with life";
System.out.println(getNextWord(text,"am"));
System.out.println(getNextWord(text,"with"));
System.out.println(getNextWord(text,"happy"));
System.out.println(getNextWord(text,"I"));
System.out.println(getNextWord(text,"life"));
}
public static String getNextWord(String text,String finditsNext){
String result = "There is no next string";
try {
int findIndex = text.indexOf(finditsNext);
String tep = text.substring(findIndex);
if(tep.indexOf(" ") >0) {
tep = tep.substring(tep.indexOf(" ") + 1);
if(tep.indexOf(" ") >0)
result = tep.substring(0, tep.indexOf(" "));
else
result = tep;
}
}catch (IndexOutOfBoundsException ex){
}
return result;
}
The output for the above is:
very
life
with
am
There is no next string
I would like to split a string at every 4th occurrence of a comma ,.
How to do this? Below is an example:
String str = "1,,,,,2,3,,1,,3,,";
Expected output:
array[0]: 1,,,,
array[1]: ,2,3,,
array[2]: 1,,3,,
I tried using Google Guava like this:
Iterable<String> splitdata = Splitter.fixedLength(4).split(str);
output: [1,,,, ,,2,, 3,,1, ,,3,, ,]
I also tried this:
String [] splitdata = str.split("(?<=\\G.{" + 4 + "})");
output: [1,,,, ,,2,, 3,,1, ,,3,, ,]
Yet this is is not the output I want. I just want to split the string at every 4th occurrence of a comma.
Thanks.
Take two int variable. One is to count the no of ','. If ',' occurs then the count will move. And if the count is go to 4 then reset it to 0. The other int value will indicate that from where the string will be cut off. it will start from 0 and after the first string will be detected the the end point (char position in string) will be the first point of the next. Use the this start point and current end point (i+1 because after the occurrence happen the i value will be incremented). Finally add the string in the array list. This is a sample code. Hope this will help you. Sorry for my bad English.
String str = "1,,,,,2,3,,1,,3,,";
int k = 0;
int startPoint = 0;
ArrayList<String> arrayList = new ArrayList<>();
for (int i = 0; i < str.length(); i++)
{
if (str.charAt(i) == ',')
{
k++;
if (k == 4)
{
String ab = str.substring(startPoint, i+1);
System.out.println(ab);
arrayList.add(ab);
startPoint = i+1;
k = 0;
}
}
}
Here's a more flexible function, using an idea from this answer:
static List<String> splitAtNthOccurrence(String input, int n, String delimiter) {
List<String> pieces = new ArrayList<>();
// *? is the reluctant quantifier
String regex = Strings.repeat(".*?" + delimiter, n);
Matcher matcher = Pattern.compile(regex).matcher(input);
int lastEndOfMatch = -1;
while (matcher.find()) {
pieces.add(matcher.group());
lastEndOfMatch = matcher.end();
}
if (lastEndOfMatch != -1) {
pieces.add(input.substring(lastEndOfMatch));
}
return pieces;
}
This is how you call it using your example:
String input = "1,,,,,2,3,,1,,3,,";
List<String> pieces = splitAtNthOccurrence(input, 4, ",");
pieces.forEach(System.out::println);
// Output:
// 1,,,,
// ,2,3,,
// 1,,3,,
I use Strings.repeat from Guava.
try this also, if you want result in array
String str = "1,,,,,2,3,,1,,3,,";
System.out.println(str);
char c[] = str.toCharArray();
int ptnCnt = 0;
for (char d : c) {
if(d==',')
ptnCnt++;
}
String result[] = new String[ptnCnt/4];
int i=-1;
int beginIndex = 0;
int cnt=0,loopcount=0;
for (char ele : c) {
loopcount++;
if(ele==',')
cnt++;
if(cnt==4){
cnt=0;
result[++i]=str.substring(beginIndex,loopcount);
beginIndex=loopcount;
}
}
for (String string : result) {
System.out.println(string);
}
This work pefectly and tested in Java 8
public String[] split(String input,int at){
String[] out = new String[2];
String p = String.format("((?:[^/]*/){%s}[^/]*)/(.*)",at);
Pattern pat = Pattern.compile(p);
Matcher matcher = pat.matcher(input);
if (matcher.matches()) {
out[0] = matcher.group(1);// left
out[1] = matcher.group(2);// right
}
return out;
}
//Ex: D:/folder1/folder2/folder3/file1.txt
//if at = 2, group(1) = D:/folder1/folder2 and group(2) = folder3/file1.txt
The accepted solution above by Saqib Rezwan does not add the leftover string to the list, if it divides the string after every 4th comma and the length of the string is 9 then it will leave the 9th character, and return the wrong list.
A complete solution would be :
private static ArrayList<String> splitStringAtNthOccurrence(String str, int n) {
int k = 0;
int startPoint = 0;
ArrayList<String> list = new ArrayList();
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ',') {
k++;
if (k == n) {
String ab = str.substring(startPoint, i + 1);
list.add(ab);
startPoint = i + 1;
k = 0;
}
}
// if there is no comma left and there are still some character in the string
// add them to list
else if (!str.substring(i).contains(",")) {
list.add(str.substring(startPoint));
break;
}
}
return list;
}
}
So say I have a string called x that = "Hello world". I want to somehow make it so that it will flip those two words and instead display "world Hello". I am not very good with loops or arrays and obviously am a beginner. Could I accomplish this somehow by splitting my string? If so, how? If not, how could I do this? Help would be appreciated, thanks!
1) split string into String array on space.
String myArray[] = x.split(" ");
2) Create new string with words in reverse order from array.
String newString = myArray[1] + " " + myArray[0];
Bonus points for using a StringBuilder instead of concatenation.
String abc = "Hello world";
String cba = abc.replace( "Hello world", "world Hello" );
abc = "This is a longer string. Hello world. My String";
cba = abc.replace( "Hello world", "world Hello" );
If you want, you can explode your string as well:
String[] pieces = abc.split(" ");
for( int i=0; i<pieces.length-1; ++i )
if( pieces[i]=="Hello" && pieces[i+1]=="world" ) swap(pieces[i], pieces[i+1]);
There are many other ways you can do it too. Be careful for capitalization. You can use .toUpperCase() in your if statements and then make your matching conditionals uppercase, but leave the results with their original capitalization, etc.
Here's the solution:
import java.util.*;
public class ReverseWords {
public String reverseWords(String phrase) {
List<String> wordList = Arrays.asList(phrase.split("[ ]"));
Collections.reverse(wordList);
StringBuilder sbReverseString = new StringBuilder();
for(String word: wordList) {
sbReverseString.append(word + " ");
}
return sbReverseString.substring(0, sbReverseString.length() - 1);
}
}
The above solution was coded by me, for Google Code Jam and is also blogged here: Reverse Words - GCJ 2010
Just use this method, call it and pass the string that you want to split out
static String reverseWords(String str) {
// Specifying the pattern to be searched
Pattern pattern = Pattern.compile("\\s");
// splitting String str with a pattern
// (i.e )splitting the string whenever their
// is whitespace and store in temp array.
String[] temp = pattern.split(str);
String result = "";
// Iterate over the temp array and store
// the string in reverse order.
for (int i = 0; i < temp.length; i++) {
if (i == temp.length - 1) {
result = temp[i] + result;
} else {
result = " " + temp[i] + result;
}
}
return result;
}
Depending on your exact requirements, you may want to split on other forms of whitespace (tabs, multiple spaces, etc.):
static Pattern p = Pattern.compile("(\\S+)(\\s+)(\\S+)");
public String flipWords(String in)
{
Matcher m = p.matcher(in);
if (m.matches()) {
// reverse the groups we found
return m.group(3) + m.group(2) + m.group(1);
} else {
return in;
}
}
If you want to get more complex see the docs for Pattern http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
Try something as follows:
String input = "how is this";
List<String> words = Arrays.asList(input.split(" "));
Collections.reverse(words);
String result = "";
for(String word : words) {
if(!result.isEmpty()) {
result += " ";
}
result += word;
}
System.out.println(result);
Output:
this is how
Too much?
private static final Pattern WORD = Pattern.compile("^(\\p{L}+)");
private static final Pattern NUMBER = Pattern.compile("^(\\p{N}+)");
private static final Pattern SPACE = Pattern.compile("^(\\p{Z}+)");
public static String reverseWords(final String text) {
final StringBuilder sb = new StringBuilder(text.length());
final Matcher wordMatcher = WORD.matcher(text);
final Matcher numberMatcher = NUMBER.matcher(text);
final Matcher spaceMatcher = SPACE.matcher(text);
int offset = 0;
while (offset < text.length()) {
wordMatcher.region(offset, text.length());
numberMatcher.region(offset, text.length());
spaceMatcher.region(offset, text.length());
if (wordMatcher.find()) {
final String word = wordMatcher.group();
sb.insert(0, reverseCamelCase(word));
offset = wordMatcher.end();
} else if (numberMatcher.find()) {
sb.insert(0, numberMatcher.group());
offset = numberMatcher.end();
} else if (spaceMatcher.find()) {
sb.insert(0, spaceMatcher.group(0));
offset = spaceMatcher.end();
} else {
sb.insert(0, text.charAt(offset++));
}
}
return sb.toString();
}
private static final Pattern CASE_REVERSAL = Pattern
.compile("(\\p{Lu})(\\p{Ll}*)(\\p{Ll})$");
private static String reverseCamelCase(final String word) {
final StringBuilder sb = new StringBuilder(word.length());
final Matcher caseReversalMatcher = CASE_REVERSAL.matcher(word);
int wordEndOffset = word.length();
while (wordEndOffset > 0 && caseReversalMatcher.find()) {
sb.insert(0, caseReversalMatcher.group(3).toUpperCase());
sb.insert(0, caseReversalMatcher.group(2));
sb.insert(0, caseReversalMatcher.group(1).toLowerCase());
wordEndOffset = caseReversalMatcher.start();
caseReversalMatcher.region(0, wordEndOffset);
}
sb.insert(0, word.substring(0, wordEndOffset));
return sb.toString();
}
I have this code:
String s = "A very long string containing " +
"many many words and characters. " +
"Newlines will be entered at spaces.";
StringBuilder sb = new StringBuilder(s);
int i = 0;
while ((i = sb.indexOf(" ", i + 20)) != -1) {
sb.replace(i, i + 1, "\n");
}
System.out.println(sb.toString());
The output of the code is:
A very long string containing
many many words and
characters. Newlines
will be entered at spaces.
The above code is wrapping the string after the next space of every 30 characters, but I need to wrap the string after the previous space of every 30 characters, like for the first line it will be:
A very long string
And the 2nd line will be
containing many
Please give some proper solution.
You can use Apache-common's WordUtils.wrap().
Use lastIndexOf instead of indexOf, e.g.
StringBuilder sb = new StringBuilder(s);
int i = 0;
while (i + 20 < sb.length() && (i = sb.lastIndexOf(" ", i + 20)) != -1) {
sb.replace(i, i + 1, "\n");
}
System.out.println(sb.toString());
This will produce the following output:
A very long string
containing many
many words and
characters.
Newlines will be
entered at spaces.
You can try the following:
public static String wrapString(String s, String deliminator, int length) {
String result = "";
int lastdelimPos = 0;
for (String token : s.split(" ", -1)) {
if (result.length() - lastdelimPos + token.length() > length) {
result = result + deliminator + token;
lastdelimPos = result.length() + 1;
}
else {
result += (result.isEmpty() ? "" : " ") + token;
}
}
return result;
}
call as wrapString("asd xyz afz","\n",5)
I know it's an old question, but . . . Based on another answer I found here, but can't remember the posters name. Kuddos to him/her for pointing me in the right direction.
public String truncate(final String content, final int lastIndex) {
String result = "";
String retResult = "";
//Check for empty so we don't throw null pointer exception
if (!TextUtils.isEmpty(content)) {
result = content.substring(0, lastIndex);
if (content.charAt(lastIndex) != ' ') {
//Try the split, but catch OutOfBounds in case string is an
//uninterrupted string with no spaces
try {
result = result.substring(0, result.lastIndexOf(" "));
} catch (StringIndexOutOfBoundsException e) {
//if no spaces, force a break
result = content.substring(0, lastIndex);
}
//See if we need to repeat the process again
if (content.length() - result.length() > lastIndex) {
retResult = truncate(content.substring(result.length(), content.length()), lastIndex);
} else {
return result.concat("\n").concat(content.substring(result.length(), content.length()));
}
}
//Return the result concatenating a newline character on the end
return result.concat("\n").concat(retResult);;
//May need to use this depending on your app
//return result.concat("\r\n").concat(retResult);;
} else {
return content;
}
}
public static void main(String args[]) {
String s1="This is my world. This has to be broken.";
StringBuffer buffer=new StringBuffer();
int length=s1.length();
int thrshld=5; //this valueis threshold , which you can use
int a=length/thrshld;
if (a<=1) {
System.out.println(s1);
}else{
String split[]=s1.split(" ");
for (int j = 0; j < split.length; j++) {
buffer.append(split[j]+" ");
if (buffer.length()>=thrshld) {
int lastindex=buffer.lastIndexOf(" ");
if (lastindex<buffer.length()) {
buffer.subSequence(lastindex, buffer.length()-1);
System.out.println(buffer.toString());
buffer=null;
buffer=new StringBuffer();
}
}
}
}
}
this can be one way to achieve
"\n" makes a wordwrap.
String s = "A very long string containing \n" +
"many many words and characters. \n" +
"Newlines will be entered at spaces.";
this will solve your problem