Implementing verification method to allow only String input in Java [duplicate] - java

I'm writing a program where the user enters a String in the following format:
"What is the square of 10?"
I need to check that there is a number in the String
and then extract just the number.
If i use .contains("\\d+") or .contains("[0-9]+"), the program can't find a number in the String, no matter what the input is, but .matches("\\d+")will only work when there is only numbers.
What can I use as a solution for finding and extracting?

try this
str.matches(".*\\d.*");

If you want to extract the first number out of the input string, you can do-
public static String extractNumber(final String str) {
if(str == null || str.isEmpty()) return "";
StringBuilder sb = new StringBuilder();
boolean found = false;
for(char c : str.toCharArray()){
if(Character.isDigit(c)){
sb.append(c);
found = true;
} else if(found){
// If we already found a digit before and this char is not a digit, stop looping
break;
}
}
return sb.toString();
}
Examples:
For input "123abc", the method above will return 123.
For "abc1000def", 1000.
For "555abc45", 555.
For "abc", will return an empty string.

I think it is faster than regex .
public final boolean containsDigit(String s) {
boolean containsDigit = false;
if (s != null && !s.isEmpty()) {
for (char c : s.toCharArray()) {
if (containsDigit = Character.isDigit(c)) {
break;
}
}
}
return containsDigit;
}

s=s.replaceAll("[*a-zA-Z]", "") replaces all alphabets
s=s.replaceAll("[*0-9]", "") replaces all numerics
if you do above two replaces you will get all special charactered string
If you want to extract only integers from a String s=s.replaceAll("[^0-9]", "")
If you want to extract only Alphabets from a String s=s.replaceAll("[^a-zA-Z]", "")
Happy coding :)

The code below is enough for "Check if a String contains numbers in Java"
Pattern p = Pattern.compile("([0-9])");
Matcher m = p.matcher("Here is ur string");
if(m.find()){
System.out.println("Hello "+m.find());
}

I could not find a single pattern correct.
Please follow below guide for a small and sweet solution.
String regex = "(.)*(\\d)(.)*";
Pattern pattern = Pattern.compile(regex);
String msg = "What is the square of 10?";
boolean containsNumber = pattern.matcher(msg).matches();

Pattern p = Pattern.compile("(([A-Z].*[0-9])");
Matcher m = p.matcher("TEST 123");
boolean b = m.find();
System.out.println(b);

The solution I went with looks like this:
Pattern numberPat = Pattern.compile("\\d+");
Matcher matcher1 = numberPat.matcher(line);
Pattern stringPat = Pattern.compile("What is the square of", Pattern.CASE_INSENSITIVE);
Matcher matcher2 = stringPat.matcher(line);
if (matcher1.find() && matcher2.find())
{
int number = Integer.parseInt(matcher1.group());
pw.println(number + " squared = " + (number * number));
}
I'm sure it's not a perfect solution, but it suited my needs. Thank you all for the help. :)

Try the following pattern:
.matches("[a-zA-Z ]*\\d+.*")

Below code snippet will tell whether the String contains digit or not
str.matches(".*\\d.*")
or
str.matches(.*[0-9].*)
For example
String str = "abhinav123";
str.matches(".*\\d.*") or str.matches(.*[0-9].*) will return true
str = "abhinav";
str.matches(".*\\d.*") or str.matches(.*[0-9].*) will return false

As I was redirected here searching for a method to find digits in string in Kotlin language, I'll leave my findings here for other folks wanting a solution specific to Kotlin.
Finding out if a string contains digit:
val hasDigits = sampleString.any { it.isDigit() }
Finding out if a string contains only digits:
val hasOnlyDigits = sampleString.all { it.isDigit() }
Extract digits from string:
val onlyNumberString = sampleString.filter { it.isDigit() }

public String hasNums(String str) {
char[] nums = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
char[] toChar = new char[str.length()];
for (int i = 0; i < str.length(); i++) {
toChar[i] = str.charAt(i);
for (int j = 0; j < nums.length; j++) {
if (toChar[i] == nums[j]) { return str; }
}
}
return "None";
}

You can try this
String text = "ddd123.0114cc";
String numOnly = text.replaceAll("\\p{Alpha}","");
try {
double numVal = Double.valueOf(numOnly);
System.out.println(text +" contains numbers");
} catch (NumberFormatException e){
System.out.println(text+" not contains numbers");
}

As you don't only want to look for a number but also extract it, you should write a small function doing that for you. Go letter by letter till you spot a digit. Ah, just found the necessary code for you on stackoverflow: find integer in string. Look at the accepted answer.

.matches(".*\\d+.*") only works for numbers but not other symbols like // or * etc.

ASCII is at the start of UNICODE, so you can do something like this:
(x >= 97 && x <= 122) || (x >= 65 && x <= 90) // 97 == 'a' and 65 = 'A'
I'm sure you can figure out the other values...

Related

I want to remove the special character and convert the next letter to uppercase "the-stealth-warrior" in Java

public class Main {
public static void main(String[] args) {
String name = "the-stealth-warrior";
for (int i = 0; i < name.length();i++){
if (name.charAt(i) == '-'){
char newName = Character.toUpperCase(name.charAt(i+1));
newName += name.charAt(i + 1);
i++;
}
}
}
}
I try to loop in every char and check if the I == '-' convert the next letter to be uppercase and append to a new String.
We can try using a split approach with the help of a stream:
String name = "the-stealth-warrior";
String parts = name.replaceAll("^.*?-", "");
String output = Arrays.stream(parts.split("-"))
.map(x -> x.substring(0, 1).toUpperCase() + x.substring(1))
.collect(Collectors.joining(""));
output = name.split("-", 2)[0] + output;
System.out.println(output); // theStealthWarrior
I think the most concise way to do this would be with regexes:
String newName = Pattern.compile("-+(.)?").matcher(name).replaceAll(mr -> mr.group(1).toUpperCase());
Note that Pattern.compile(...) can be stored rather than re-evaluating it each time.
A more verbose (but probably more efficient way) to do it would be to build the string using a StringBuilder:
StringBuilder sb = new StringBuilder(name.length());
boolean uc = false; // Flag to know whether to uppercase the char.
int len = name.codePointsCount(0, name.length());
for (int i = 0; i < name.len; ++i) {
int c = name.codePointAt(i);
if (c == '-') {
// Don't append the codepoint, but flag to uppercase the next codepoint
// that isn't a '-'.
uc = true;
} else {
if (uc) {
c = Character.toUpperCase(c);
uc = false;
}
sb.appendCodePoint(c);
}
}
String newName = sb.toString();
Note that you can't reliably uppercase single codepoints in specific locales, e.g. ß in Locale.GERMAN.

Upper case conversion - convert the first letter of each word in the string to uppercase

Some test cases are not working. May I know where I went Wrong. the test case "i love programming is working but other test case which idk are not working.
class Solution
{
public String transform(String s)
{
// code here
char ch;
// String s = "i love programming";
String res="";
ch = s.charAt(0);
ch = Character.toUpperCase(s.charAt(0));
res +=ch;
for(int i=1;i<s.length();i++){
if(s.charAt(i) == ' '){
//System.out.println(i);
ch = Character.toUpperCase(s.charAt(i+1));
res+=' ';
res+=ch;
i++;
}else {
res+=s.charAt(i);
}
}
return res;
}
}
//Some test cases are not working. May I know where I went Wrong?
This solution worked for me really well all the test cases passed. Thank you.
class Solution
{
public String transform(String s)
{
// code here
char ch;
// String s = "i love programming";
String res="";
ch = s.charAt(0);
ch = Character.toUpperCase(s.charAt(0));
res +=ch;
for(int i=1;i<s.length();i++){
if(s.charAt(i-1) == ' '){
//System.out.println(i);
ch = Character.toUpperCase(s.charAt(i));
res+=ch;
}else {
res+=s.charAt(i);
}
}
return res;
}
}
I tried my best to understand your code as the formatting got a bit butchered in markdown I am assuming but nevertheless I gathered that this was close to what your solution was:
public class MyClass {
public static void main(String args[]) {
int i = 0;
String greet = "hello world";
String res = "";
res += Character.toUpperCase(greet.charAt(i++));
for (; i < greet.length(); i++){
if (greet.charAt(i) == ' '){
res = res + greet.charAt(i) + Character.toUpperCase(greet.charAt(i + 1) );
i++;
}else{
res += greet.charAt(i);
}
}
System.out.println(res);
}
}
For me this worked, but this is assuming that spaces only ever occur between words. Perhaps the answer to your question lies in these test cases and more importantly the assumptions behind these test cases. Try to gather more info about that if you can :)
There is an attempt to make uppercase a next character after the space (which should be done only if this character is a letter and if this charactrer is available). Similarly the first character of the sentence is upper cased without checking if this first letter is a letter.
It may be better to use a boolean flag which should be reset upon applying an upper case to a letter. Also, StringBuilder should be used instead of concatenating a String in the loop.
So the improved code may look as follows with more rules added:
make the first letter in the word consisting of letters and/or digits upper case
words are separated with any non-letter/non-digit character except ' used in contractions like I'm, there's etc.
check for null/ empty input
public static String transform(String s) {
if (null == s || s.isEmpty()) {
return s;
}
boolean useUpper = true; // boolean flag
StringBuilder sb = new StringBuilder(s.length());
for (char c : s.toCharArray()) {
if (Character.isLetter(c) || Character.isDigit(c)) {
if (useUpper) {
c = Character.toUpperCase(c);
useUpper = false;
}
} else if (c != '\'') { // any non-alphanumeric character, not only space
useUpper = true; // set flag for the next letter
}
sb.append(c);
}
return sb.toString();
}
Tests:
String[] tests = {
"hello world",
" hi there,what's up?",
"-a-b-c-d",
"ID's 123abc-567def"
};
for (String t : tests) {
System.out.println(t + " -> " + transform(t));
}
Output:
hello world -> Hello World
hi there, what's up? -> Hi There,What's Up?
-a-b-c-d -> -A-B-C-D
ID's 123abc-567def -> ID's 123abc-567def
Update
A regular expression and Matcher::replaceAll(Function<MatchResult, String> replacer) available since Java 9 may also help to capitalize the first letters in the words:
// pattern to detect the first letter
private static final Pattern FIRST_LETTER = Pattern.compile("\\b(?<!')(\\p{L})([\\p{L}\\p{N}]*?\\b)");
public static String transformRegex(String s) {
if (null == s || s.isEmpty()) {
return s;
}
return FIRST_LETTER.matcher(s)
.replaceAll((mr) -> mr.group(1).toUpperCase() + mr.group(2));
}
Here:
\b - word boundary
(?<!') - negative lookbehind for ' as above, that is, match a letter NOT preceded with '
\p{L} - the first letter in the word (Unicode)
([\p{L}\p{N}]*\b) - followed by a possibly empty sequence of letters/digits

how to reverse only numbers in a string

INPUT : 123ABC458
OUTPUT : 321ABC854
public static void main(String []args){
String str="123ABC564";
int count=0;
int ans=0;
int firstindex=0;
char[] ch = str.toCharArray();
for(int i=0;i<ch.length;i++){
if(Character.isDigit(ch[i])){
if(ans==0){
firstindex=i;
}
count++;
}
else{
int lastindex=count+firstindex-1;
while(firstindex<lastindex){
char temp=ch[firstindex];
ch[firstindex]=ch[lastindex];
ch[lastindex]=temp;
firstindex++;
lastindex--;
}
ans=0;
count=0;
firstindex=0;
}
}
for (char c : ch){
System.out.print(c);
}
}
}
Can anyone tell me what's wrong with this code
The output which I am getting using this code is 12BA3C564
You can use the Java regex API and StringBuilder to solve it easily. The regex, \d+ specifies one or more digits. Using the Java regex API, you find the numbers, their start position and the end positions which you can use to build the required string.
Demo:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
// Tests
String[] samples = { "123ABC458", "123ABC458XYZ", "123ABC458XYZ367", "ABC123XYZ", "ABC123XYZ" };
for (String s : samples)
System.out.println(numbersInverted(s));
}
static String numbersInverted(String str) {
StringBuilder sb = new StringBuilder();
Matcher matcher = Pattern.compile("\\d+").matcher(str);
int lastInitialPos = 0;
while (matcher.find()) {
int start = matcher.start();
String inverted = new StringBuilder(matcher.group()).reverse().toString();
sb.append(str.substring(lastInitialPos, start)).append(inverted);
lastInitialPos = matcher.end();
}
if (sb.length() == 0) // If no number was found
return str;
else
return sb.append(str.substring(lastInitialPos)).toString();
}
}
Output:
321ABC854
321ABC854XYZ
321ABC854XYZ763
ABC321XYZ
ABC321XYZ
ONLINE DEMO
Here is a concise version using string splitting:
String input = "123ABC458";
String[] parts = input.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
StringBuilder sb = new StringBuilder();
for (String part : parts) {
if (part.matches("\\d+")) {
StringBuilder num = new StringBuilder(part);
sb.append(num.reverse());
}
else {
sb.append(part);
}
}
System.out.println(sb.toString()); // 321ABC854
The splitting operation used above generates a string array of either numbers or letters. Then, we iterate that array and selectively reverse the number strings using StringBuilder#reverse.
This task can be implemented without regular expressions, splitting the input string into substring etc. merely with the help of StringBuilder::insert(int offset, char c) and StringBuilder::append(char c) using simple index calculation for insert:
public static String revertDigits(String str) {
if (str == null || str.isEmpty()) {
return str;
}
StringBuilder sb = new StringBuilder(str.length());
for (int i = 0, j = 0, n = str.length(); i < n; i++) {
char c = str.charAt(i);
if (Character.isDigit(c)) {
sb.insert(j, c); // append in "reverse" mode
} else {
sb.append(c);
j = i + 1; // store the last position of a non-digit
}
}
return sb.toString();
}
Test:
String str="123ABC564";
System.out.println(str + '\n' + revertDigits(str));
Output
123ABC564
321ABC465
Can anyone tell me what's wrong with this code
I believe I have spotted two bugs in your code:
You are never setting ans to anything else than 0. So your if condition ans==0 will always be true. If I have understood the purpose of that variable correctly, you may want to replace it with a boolean called something like insideNumber and set it to true when you detect a digit and to false when you detect that a char is not a digit. Your if statement then becomes if (insideNumber) …
You don’t take a number at the end of your string into account. You can check this statement by appending a letter to your string and see that 564 will then be reversed into 465. To reverse a trailing number correctly: after your loop again check whether you were inside a number, and if so, reverse the last number from firstindex up to the end of the string.
You can get all the numbers from the string as the first move, and then replace the input with the reversed string of the numbers. Example:
public static void main(String[] args)
{
String input = "123ABC458";
Matcher m = Pattern.compile("\\d+").matcher(input);
while(m.find())
input = input.replace(m.group(), new StringBuilder(m.group()).reverse());
System.out.println(input);
}
As an alternative solution, from Java 9 you could also make use of Matcher#replaceAll and reverse every match for 1 or more digits.
String result = Pattern.compile("\\d+")
.matcher("123ABC458")
.replaceAll(m -> new StringBuilder(m.group()).reverse().toString());
System.out.println(result);
Output
321ABC854
Java demo

How do I reverse this basic encrypt?

public static String basicEncrypt(String s) {
String toReturn = "";
for (int j = 0; j < s.length(); j++) {
toReturn += (int)s.charAt(j);
}
//System.out.println("Encrypt: " + toReturn);
return toReturn;
}
Is there any way to reverse this to find the original string? Much appreciated.
Under the assumption that you only use ASCII characters (32-255 codes) the algorithm is simple:
Take the first character of input
If it's 1 or 2 - take and cut off next two digits and convert to character
If it's any other character - take and cut off next digit and convert to character
Go to 1. if some input left
Here is a quick'n'dirty Scala implementation:
def decrypt(s: String): String = s.headOption match {
case None => ""
case Some('1') | Some('2') => s.substring(0, 3).toInt.toChar + decrypt(s.substring(3))
case Some(_) => s.substring(0, 2).toInt.toChar + decrypt(s.substring(2))
}
Yes, if taken in account that your original string consists of characters between and including (32) and unicode charcode 299, see http://www.asciitable.com/
Psuedo code
ret=<empty string>
while not end of string
n=next number from string
if n<3 charcode= n + next 2 numbers
else
charcode=n + next number
ret=ret + character(charcode)
end while
Charcodes under space (newlines and carriage returns)and above 299 will thwart this algorithm. This algorithm can be fixed to include characters up to charcode 319.
private static String basicDecrypt(String s) {
String result = "";
String buffer = "";
for (int i = 0; i < s.length(); i++) {
buffer += s.charAt(i);
if ((buffer.charAt(0) == '1' && buffer.length() == 3) || (buffer.charAt(0) != '1' && buffer.length() == 2)) {
result += (char) Integer.parseInt(buffer);
buffer = "";
}
}
return result;
}
This is a very basic decryption method. It will only work for [A-Za-z0-9]+ US ASCII.
Just for the fun of it, another couple of versions; Java, US-ASCII only, chars 0x14-0xc7;
public static String basicDecrypt(String input)
{
StringBuffer output = new StringBuffer();
Matcher matcher = Pattern.compile("(1..|[2-9].)").matcher(input);
while(matcher.find())
output.append((char)Integer.parseInt(matcher.group()));
return output.toString();
}
For 0x1e-0xff, replace the regex with "([12]..|[3-9].)"
...and a somewhat briefer Linq'y C# version.
private static string BasicDecrypt(string input)
{
return new string(Regex.Matches(input, "(1..|[2-9].)").Cast<Match>()
.Select(x => (char) Int32.Parse(x.Value)).ToArray());
}

character checking

if (c=='a' || c=='e' || c=='i' || c=='o' || c=='u') {
count++;
When i give the above statement it returns number of vowels in a word only if the given word is in lowercase (ie: input: friend output 2 vowels). I Want to know even if i give uppercase or mixed it should return number of vowels. How to do it?
One succint, simple way to do this without doing 10 comparisons:
if ("aeiouAEIOU".indexOf(c) != -1) { count++; }
Here there is a complete example - note they turn the string to lower case before checking the vowels.
You can also try with a case insensitive regular expression, example from http://www.shiffman.net/teaching/a2z/regex/:
String regex = "[aeiou]";
Pattern p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
int vowelcount = 0;
Matcher m = p.matcher(content); // Create Matcher
while (m.find()) {
//System.out.print(m.group());
vowelcount++;
}
If you want to get upper or lowercase a simple approach seems to be the following:
Iterate over all the characters in the word and do the following test:
if (c=='a' || c=='e' || c=='i' || c=='o' || c=='u'
|| c=='A' || c=='E' || c=='I' || c=='O' || c=='U')
{ count++ };
You can use tests like:
Character.toLowerCase(c) == 'a'
instead.
I tell you one thing, if you give the out put in upper case then in your code accept given out put in lower case.
if string str='FRIEND'
handle str.Tolower();
Please try this I think your problem resoloved.
How about:
if (Arrays.asList('a', 'e', 'i', 'o', 'u').contains(Character.toLowerCase(c))) {
...
}
I would also static final the list as well.
Here is a quite simple utility class :
public class Main {
public static int countChars(String string, Character... characters) {
return countChars(string, new HashSet<Character>(Arrays.asList(characters)));
}
public static int countChars(String string, Set<Character> characters) {
int count = 0;
for(int i = 0; i < string.length(); i++){
if(characters.contains(string.charAt(i))){
count++;
}
}
return count;
}
public static int countCharsIgnoreCase(String string, Character... characters) {
return countCharsIgnoreCase(string, new HashSet<Character>(Arrays.asList(characters)));
}
public static int countCharsIgnoreCase(String string, Set<Character> characters) {
Set<Character> finalCharacters = new HashSet<Character>();
for (Character character : characters) {
finalCharacters.add(Character.toUpperCase(character));
finalCharacters.add(Character.toLowerCase(character));
}
return countChars(string, finalCharacters);
}
}
code on ideone
Not the most efficient solution, but perhaps the shortest? :)
int vowelCount = (inputString+" ").split("(?i)[aoeuiy]").length - 1
Btw, am I the only one counting 'y' as a wovel? ;)
Didn't see a Set yet :-(
static Character charvowels[] = { 'A','I','U','E','O','a','i','u','e','o' };
static Set<Character> vowels = new HashSet<Character>(Arrays.asList(charvowels));
...
public void countVowel(char c) {
if (vowels.contains(c)) count++;
}
Using Guava's CharMatcher:
private final CharMatcher vowels = CharMatcher.anyOf("aeiouAEIOU");
...
// somewhere in your method:
if (vowels.matches(c)) {
...
}

Categories

Resources