Why not just String substr = word.substring(word.length() - 3)?
Update
Please make sure you check that the String is at least 3 characters long before calling substring():
if (word.length() == 3) {
return word;
} else if (word.length() > 3) {
return word.substring(word.length() - 3);
} else {
// whatever is appropriate in this case
throw new IllegalArgumentException("word has fewer than 3 characters!");
}
Answer from Egor on Stack OverflowWhy not just String substr = word.substring(word.length() - 3)?
Update
Please make sure you check that the String is at least 3 characters long before calling substring():
if (word.length() == 3) {
return word;
} else if (word.length() > 3) {
return word.substring(word.length() - 3);
} else {
// whatever is appropriate in this case
throw new IllegalArgumentException("word has fewer than 3 characters!");
}
I would consider right method from StringUtils class from Apache Commons Lang:
http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html#right(java.lang.String,%20int)
It is safe. You will not get NullPointerException or StringIndexOutOfBoundsException.
Example usage:
StringUtils.right("abcdef", 3)
You can find more examples under the above link.
So there are two problems here:
Firstly you're calling fname.Length(3), which doesn't make sense as String doesn't have a Length(int n) method on it. What it does have is a substring(int) method and a length() method, which you can use as follows:
String middlePart = fname.substring(fname.length() - 3);
As outlined in the linked JavaDocs, String.substring() "Returns a new string that is a substring of this string. The substring begins with the character at the specified index and extends to the end of this string.". So if we can provide it with the index (or position) within the String fname where we want to start copying from.
If I've got a String such as "Chicken", and I want the last 3 characters, I'd call "Chicken".substring(4), and the result would be "ken" (Strings are zero-indexed, so the character 'k' has index 4).
Instead of hard coding the index where I want to start the substring from, I use the String.length() method which tells me how long a String is, and subtract 3. In the above example, "Chicken".length() is 7, and so "Chicken".length() - 3 is the index where you should start substring-ing if you want the last 3 characters.
String lastThreeChars = string.substring(string.length() - 3);
Why has nobody given the obvious answer?
sed 's/.*\(...\)/\1/'
… or the slightly less obvious
grep -o '...$'
Admittedly, the second one has the drawback that lines with fewer than three characters vanish; but the question didn’t explicitly define the behavior for this case.
Keeping it simple - tail
We should not need a regular expression, or more than one process, just to count characters.
The command tail, often used to show the last lines of a file, has an option -c (--bytes), which seems to be just the right tool for this:
$ printf 123456789 | tail -c 3
789
(When you are in a shell, it makes sense to use a method like in the answer of mikeserv, because it saves starting the process for tail.)
Real Unicode characters?
Now, you ask for the last three characters; That's not what this answer gives you: it outputs the last three bytes!
As long as each character is one byte, tail -c just works. So it can be used if the character set is ASCII, ISO 8859-1 or a variant.
If you have Unicode input, like in the common UTF-8 format, the result is wrong:
$ printf 123αβγ | tail -c 3
�γ
In this example, using UTF-8, the greek characters alpha, beta and gamma are two bytes long:
$ printf 123αβγ | wc -c
9
The option -m can at least count the real unicode characters:
printf 123αβγ | wc -m
6
Ok, so the last 6 bytes will give us the last 3 characters:
$ printf 123αβγ | tail -c 6
αβγ
So, tail does not support handling general characters, and it does not even try (see below): It handles variable size lines, but no variable size characters.
Let's put it this way: tail is just right for the structure of the problem to solve, but wrong for the kind of data.
GNU coreutils
Looking further, it turns out that thee GNU coreutils, the collection of basic tools like sed, ls, tail and cut, is not yet fully internationalized. Which is mainly about supporting Unicode.
For example, cut would be a good candidate to use instead of tail here for character support; It does have options for working on bytes or chars, -c (--bytes) and -m (--chars);
Only that -m/--chars is, as of version
cut (GNU coreutils) 8.21, 2013,
not implemented!
From info cut:
`-c CHARACTER-LIST'
`--characters=CHARACTER-LIST'
Select for printing only the characters in positions listed in CHARACTER-LIST.
The same as `-b' for now, but internationalization will change that.
See also this answer to Can not use `cut -c` (`--characters`) with UTF-8?.
Assuming that the url will end with .XXX (continuous extension)
String[] splitted = url.split("\\.");
return (splitted[splitted.length-1]); //will return the last string after the last "."
Where url is your url (www.google.com in this case).
Note that if the url is http://www.google.com/ then the code will return .com/. So you need to perform a check if the result contains / character. (Hint: look for contains in the String API).
Get the last index of the character '.', from there increment once then go till there are no other characters or you reach a '/' character.
I think you should create a new list to storage the sub string. Do you know when your for-cycle break? I debugged it and get that it will break when your alist.size()=0. The exception causes when the aList.get(i).length()<3. So you just do like this:
`
List<String> aList = new ArrayList<String>();
aList.add("4:78:34");
aList.add("5:8:34");
aList.add("8:18:90");
aList.add("2:8:40");
List<String> subList = new ArrayList<String>();
for (int i = 0; i < aList.size(); i++)
{
String str = aList.get(i).substring(0, aList.get(i).length() - 3);
subList.add(str);
}
System.out.println(subList);`
I worked up a recursive function for you to call to get the string after the right most colon. So if you can find another colon, it keeps looking further. If it can't it returns what's left.
public static String getRight(String str) {
if (str.indexOf(':') > 0) {
str = getRight(str.substring(str.indexOf(':')+1));
}
return str;
}
As PM 77-1 said, you are adding more items to your list so it can't ever get to the end of the list. You need to store the original count if you are to ever get out of your for loop. Here is your fully modified code tested and working:
public class SplitString {
public static void main(String[] args) {
List<String> aList = new ArrayList<String>();
aList.add("4:78:34");
aList.add("5:8:34");
aList.add("8:18:90");
aList.add("2:8:40");
int original_size = aList.size();
for(int i=0;i<original_size;i++){
String str = aList.get(i);
aList.add(getRight(str));
}
System.out.println(aList);
}
public static String getRight(String str) {
if (str.indexOf(':') > 0) {
str = getRight(str.substring(str.indexOf(':')+1));
}
return str;
}
}
Good try. The only problem is you choose the wrong remainder of the division since elements start from 0.
Try this condition:
if (i % 3 == 2)
Your current approach is off in the remainder (as already mentioned), however a much faster approach is available; instead of iterating every character, start with the third character and increase your index by three on each iteration. Remember, the third character is at index two (0, 1, 2). Also, it is better to use a StringBuilder over String concatenation (as Java String is immutable). Like,
StringBuilder sb = new StringBuilder();
for (int i = 2; i < string.length(); i += 3) {
sb.append(string.charAt(i));
}
return sb.toString();
That piece of code does exactly the opposite of what you want. Now let's see why and how we can modify it.
Quick solution
You can modify the code as follows to do what you want:
String lastNchars = s.substring( Math.max(0, s.length()-n));
Explanation
According to the official documentation, Java String class has a special method called substring().
The signature of the method is the following (with overload):
public String substring(int beginIndex, int endIndex))
public String substring(int beginIndex)
The first method accepts 2 parameters as input:
beginIndex: the begin index of the substring, inclusive.endIndex: the end index of the substring, exclusive.
The second overload will automatically consider as endIndex the length of the string, thus returning "the last part"
Both methods return a new String Object instance according to the input parameters just described.
How do you pick up the right sub-string from a string? The hint is to think at the strings as they are: an array of chars. So, if you have the string Hello world you can logically think of it as:
[H][e][l][l][o][ ][w][o][r][l][d]
[0]...............[6]......[9][10]
If you choose to extract only the string world you can thus call the substring method giving the right "array" indexes (remember the endIndex is exclusive!):
String s = "Hello world";
s.substring(6,11);
In the code snippet you provided, you give a special endIndex:
Math.min(s.length(), n);
That is exactly up to the n th char index taking into account the length of the string (to avoid out of bound conditions).
What we did at the very beginning of this answer was just calling the method and providing it with the beginning index of the substring, taking into account the possible overflow condition if you choose a wrong index.
Please note that any String Object instance can take advantage of this method, take a look at this example, for instance:
System.out.println("abc");
String cde = "cde";
System.out.println("abc" + cde);
String c = "abc".substring(2,3);
String d = cde.substring(1, 2);
As you see even "abc", of course, has the substring method!
Try,
String upToNCharacters = s.substring(s.length()-lastCharNumber);