So first of all i would like to clear things off by saying that this is for a Minecraft plugin. So I have a method to spawn some mobs (You dont know what mobs it is), and give them custom names. The names are based on numbers. But I also have a sequence of characters in its name. So for instance if the name for the mob was "355 Blaze" it would return an int of 355, and cut the rest out. How should I do this? Currently I use substring but it doesnt work as if the number goes above 9 it will return the first number only.
If its separated by space, use substring based on the location of first space:
Integer mobId = new Integer(fullMobName.substring(0, fullMobName.indexOf(" ")));
Simply use a regex.
private final static Pattern p = Pattern.compile("\\d+");
static String firstNum(String s) {
Matcher m = p.matcher(s);
return m.find() ? m.group() : null;
}
You can use a regex expression in replace method
String s = "355 Blaze";
s.replaceAll("[A-Za-z\\s]+", "");
Then you can cast to int.
Do it without a regex (assuming the number is positive and fits in an int):
int i = 0;
// Skip past non-digits.
while (i < s.length() && !Character.isDigit(s.charAt(i))) {
++i;
}
if (i < s.length()) {
int num = 0;
// Accumulate the digits into the result.
while (i < s.length() && Character.isDigit(s.charAt(i))) {
num = 10 * num + Character.getNumericValue(s.charAt(i));
++i;
}
return num;
}
// No digits found.
throw new NoSuchElementException("No digits found!");
If it only contains digits followed by letters( with possibly an optional space), this will also work:
String ss[] = original.split("a-zA-Z ]", 2);
//ss[0] contains the numbers
Related
I'm currently trying to check if a string contains 3 digits or more. If it does, then it is valid. How can I fix it?
System.out.print("Enter a string: "); //111Hello <-- valid
String word = input.nextLine();
boolean numbers = word.matches(".*\\d{3,}");
System.out.println(numbers);
Output:
Invalid
Here are some examples:
Input:
Hello244
Output:
Valid
Input:
3Hello
Output:
Invalid
Input:
6Hello2Hello5
Output:
Valid
This is easy to do using a regular expression, because the set of strings containing at least three digits is a regular language - precisely what regular expressions are designed to recognise.
public boolean hasThreeDigits(String s) {
return s.matches(".*\\d.*\\d.*\\d.*");
}
The regex .*\d.*\d.*\d.* matches three digits with anything before, after or in between.
Let's do this with regular expressions. That doesn't really seem required, but let's assume this is an assignment:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FindDigits {
public static final Pattern DIGIT_PATTERN = Pattern.compile("\\p{Digit}");
private static int countDigits(String input) {
final Matcher m = DIGIT_PATTERN.matcher(input);
int c = 0;
while (m.find()) {
c++;
}
return c;
}
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
final int c = countDigits(args[i]);
System.out.printf("Input : \"%s\"%nOutput: %s%n", args[i], c >= 3 ? "Valid" : "Invalid");
}
}
}
This answer assumes that the input is a set of strings on the command line. It defines a function to count the occurrences of pattern consisting of a single digit. It could of course stop counting at 3.
I'm mainly posting this because Matcher.find is often overlooked as it doesn't have a convenience method defined in String. It often makes for much easier to read regular expressions as you don't need to define what you are not looking for. Otherwise you're stuck with regular expressions strings such as ".*\\d.*\\d.*\\d.*" which are kind of horrible and do not scale well.
Instead of the while loop you can also use m.results().count() on a later version of the Java runtime. In that case a one-liner would be:
long count = Pattern.compile("\\p{Digit}").matcher(input).results().count();
Why not have a counter and loop over each character and then test if its a digit?
This is pseudo code :
System.out.print("Enter a string: "); //111Hello <-- valid
String word = input.nextLine();
int numberOfDigits = countDigits(word, 3);
if (numberOfDigits) >= 3{//...
int countDigits(String val, int max){
int cnt = 0;
for(int i =0; i < val.length(); i++){
char c = val.charAt(i);
if(Character.isDigit(c){
cnt++;
}
if(cnt == max)return;
}
return cnt;
}
https://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#isDigit(char)
Maybe not the most elegant solution, but pretty short and straightforward:
System.out.println(input.replaceAll("\\D","").length() > 2);
I prefer kaya3's solution the most
I want to achieve something like this.
String str = "This is just a sample string";
List<String> strChunks = splitString(str,8);
and strChunks should should be like:
"This is ","just a ","sample ","string."
Please note that string like "sample " have only 7 characters as with 8 characters it will be "sample s" which will break down my next word "string".
Also we can go with the assumption that a word will never be larger than second argument of method (which is 8 in example) because in my use case second argument is always static with value 32000.
The obvious approach that I can think of is looping thru the given string, breaking the string after 8 chars and than searching the next white space from the end. And then repeating same thing again for remaining string.
Is there any more elegant way to achieve the same. Is there any utility method already available in some standard third libraries like Guava, Apache Commons.
Splitting on "(?<=\\G.{7,}\\s)" produces the result that you need (demo).
\\G means the end of previous match; .{7,} means seven or more of any characters; \\s means a space character.
Not a standard method, but this might suit your needs
See it on http://ideone.com/2RFIZd
public static List<String> splitString(String str, int chunksize) {
char[] chars = str.toCharArray();
ArrayList<String> list = new ArrayList<String>();
StringBuilder builder = new StringBuilder();
int count = 0;
for(char character : chars) {
if(count < chunksize - 1) {
builder.append(character);
count++;
}
else {
if(character == ' ') {
builder.append(character);
list.add(builder.toString());
count = 0;
builder.setLength(0);
}
else {
builder.append(character);
count++;
}
}
}
list.add(builder.toString());
builder.setLength(0);
return list;
}
Please note, I used the human notation for string length, because that's what your sample reflects( 8 = postion 7 in string). that's why the chunksize - 1 is there.
This method takes 3 milliseconds on a text the size of http://catdir.loc.gov/catdir/enhancements/fy0711/2006051179-s.html
Splitting String using method 1.
String text="This is just a sample string";
List<String> strings = new ArrayList<String>();
int index = 0;
while (index < text.length()) {
strings.add(text.substring(index, Math.min(index + 8,text.length())));
index += 8;
}
for(String s : strings){
System.out.println("["+s+"]");
}
Splitting String using Method 2
String[] s=text.split("(?<=\\G.{"+8+"})");
for (int i = 0; i < s.length; i++) {
System.out.println("["+s[i]+"]");
}
This uses a hacked reduction to get it done without much code:
String str = "This is just a sample string";
List<String> parts = new ArrayList<>();
parts.add(Arrays.stream(str.split("(?<= )"))
.reduce((a, b) -> {
if (a.length() + b.length() <= 8)
return a + b;
parts.add(a);
return b;
}).get());
See demo using edge case input (that breaks some other answers!)
This splits after each space, then either joins up parts or adds to the list depending on the length of the pair.
I am trying to print a substring using index value. I need to exclude the blank space while counting but it should print the output along with blank space. I want to display, say, n alphabets from the main string. The blank spaces will be as they are but the number of alphabets from the lower bound to upper bound index should be n. My code is
public class Test {
public static void main(String args[])
{
String Str=new String("Welcome to the class");
System.out.println("\nReturn value is:");
System.out.println(Str.substring(2,9));
}
}
Output:
lcome t
In the above mentioned code, it counts the space between the "Welcome" and "to". i need not want to count the space between them. My expected output is lcome to
You could use simple mathematics. Just substring it, remove all whitespaces and compare the original length to the String without whitespaces. Afterwards add the difference in size to your end index for the substring.
public static void main(String args[]) {
String Str = "Welcome to the class";
System.out.println("\nReturn value is:");
String sub = Str.substring(2, 9);
String wsRemoved = sub.replaceAll(" ", "");
String wsBegginingRemoved = sub.replaceAll("^ *", "");
String outputSub = Str.substring(2+(sub.length()-wsBegginingRemoved.length()), 9+(sub.length()-wsRemoved.length()+(sub.length() - wsBegginingRemoved.length())));
System.out.println(outputSub);
}
Edit: not ignoring leading whitespaces anymore
O/P
lcome to
O/P "My name is Earl"
name is E
One way would be to extract it to using a regex ^.{2}([^ ] *){7}.
Another option is to use a simple for loop to traverse the string and calculate the end point to use for substring.
int non_whitespace = 0; int i;
for(i = 2; non_whitespace < 7; ++non_whitespace, ++i) {
while (str.charAt(i) == ' ') ++i;
}
return str.substring(2, i);
It is up to you which method do you consider more readable, and assess which one leads to better performance if speed is a concern.
What you want to do is display n number of characters from the string including the spaces but n doesn't include the no. of blank spaces. For that, you could simply be using a loop instead of a library function.
The Logic: Keep displaying characters of the String str from index = 2 to index = 9-1 in a while loop. If the current character is a blank space, then increase the value of n, which is the upper bound of the string index for the sub string, by 1, i.e., the program will now display an extra character beyond the upper bound for each blank space encountered.
Consider the code below.
String str = "Welcome to the class";
int index = 2, n = 9;
while(index < n){
char c = str.charAt(index);
System.out.print(c);
if(c==' ')
n++;
index++;
}
Output: lcome to
Hope you can understand this code.
EDIT
As #Finbarr O'B said, a check to prevent StringIndexOutOfBoundsException would be necessary for the program for which, the loop will have to be defined as:
while(index < n && index < str.length()){
...
}
If you don't want to use regex, you can implement your own version of substring. The straightforward solution:
private static String substring(int begin, int end, String str) {
StringBuilder res = new StringBuilder();
while (begin < end) {
if (str.charAt(begin) == ' ') {
end++;
}
res.append(str.charAt(begin));
begin++;
}
return res.toString();
}
The trick here is to ignore the "count" of a space, by incrementing end when it's encountered, forcing the loop to make one extra iteration.
The code complexity is O(n).
System.out.println(substring(2, 9, "Welcome to the class"));
>> lcome to
You could use replaceFirst for this:
String Str = "Welcome to the class"; // remove new String()
Str = Str.replaceFirst("^ *", "");
System.out.println("\nReturn value is:");
System.out.println(Str.substring(2, 10)); // increment end index by 1
Output:
lcome to
I want to extract trailing zeros from a string for eg
//8320987112741390144276341183223364380754172606361245952449277696409600000000000000
should yield
14
my approach was to first find the length of above string then subtract it by length of the
stripped trailing zero string.
I tried to find the later using BigDecimal stripTrailingZeros() method but it is only removing zeros after decimal
for eg
1200.000 is converted to 1200 by stripTrailingZeros() method but i want 12 as output
any idea how to solve this problem?
The simplest option would probably be to use String.replaceAll:
text = text.replaceAll("[0.]*$", "");
The $ makes sure it's only trimming the end of the string.
Note that if you start with "0" you'll end up with an empty string - think about what you want the result to be in that situation.
If you want the length of trailing zeroes, you could do this regex :
public static void main(String[] args) {
String s = "8320987112741390144276341183223364380754172606361245952449277696409600000000000000";
Pattern p = Pattern.compile("0+$");
Matcher m = p.matcher(s);
m.find();
String val = m.group();
System.out.println(val);
System.out.println(val.length());
}
O/P :
00000000000000
14
well - this is simple but a compute-intesiv solution...
String str = "8320987112741390144276341183223364380754172606361245952449277696409600000000000000";
System.out.println(str);
int count = 0;
char c = '0';
do {
c = str.charAt(str.length()-1);
if (c == '0' ){
str = str.substring(0, str.length() - 1);
count ++;
}
}while(c == '0' );
System.out.println(str);
System.out.println("amount:"+amount);
but it's a very obvious solution... (just remove last zero...until there is no more...)
Does this answer fulfills your requirement?
String str = "8320987112741390144276341183223364380754172606361245952449277696409600000000000000";
String withoutTrailingZeroes = "";
for (int i = str.length() - 1; i >= 0; i--) {
String charFromString = Character.toString(str.charAt(i));
if (charFromString.equals("0")) {
withoutTrailingZeroes += str.charAt(i);
} else {
break;
}
}
System.out.println(str);
System.out.println(str.replace(withoutTrailingZeroes, "")); // string without trailing zeros
System.out.println(withoutTrailingZeroes); // trailing zeroes
System.out.println(withoutTrailingZeroes.length()); // trailing zeroes length
OK, expanding on Jon's answer, and assuming that you don't want to count the decimal point, then the following code should cope with both integers and decimal numbers in your string:
// Start by taking note of the original string length
int startLength = text.length();
// Remove any trailing zeroes
text = text.replaceAll("0*$", "");
// Remove any zeroes immediately to the left of any trailing decimal point
text = text.replaceAll("0*.$", ".");
// Find the number of zeroes by subtracting the lengths
int numZeroes = startLength - text.length();
or if you want it in a single statement:
int numZeroes = text.length() - text.replaceAll("0*$", "").replaceAll("0*.$", ".").length();
Which looks horrible, but has the advantage of not altering the original string.
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.