In the program I am trying to look for pattern in content. If any of the pattern H Q 9 is found in string taken by user it should print YES else NO. So I used three bool flag1 flag2 flag3. My code gives wrong output if input is codeforces. Desired output is NO instead of YES.
public static void main(String[] args) {
boolean flag1 = false;
boolean flag2 = false;
boolean flag3 = false;
Scanner in = new Scanner(System.in);
String s = in.nextLine();
String text = s;
String pat1 = ".*H*.";
String pat2 = ".*Q*.";
String pat3 = ".*9*.";
//boolean isMatch = Pattern.matches(pattern, content);
flag1 = Pattern.matches(pat1, text);
flag2 = Pattern.matches(pat2, text);
flag3 = Pattern.matches(pat3,text);
if (flag1 == true || flag2 == true || flag3 == true)
System.out.println("YES");
else
System.out.println("NO");
}
Your regexps are wrong - H* means "any number of Hs, including zero", and likewise for both other regexps.
Thus, .*H*. means that your text should contain an arbitrary number of "something", then an arbitrary number of Hs (or none, as "zero Hs" is also allowed), and then an arbitrary letter.
codeforces fulfils these criteria, as it contains of an arbitrary number of letters, no H and ends with an arbitrary letter.
Your regexps will match any input which has at least once character.
Using three regular expressions is redundant. I recommend just using one.
I also refactored and reformatted your code.
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String s = in.nextLine();
boolean matches = Pattern.matches(".*[HQ9].*", s);
if (matches)
{
System.out.println("YES");
} else
{
System.out.println("NO");
}
}
You could compress the method even further:
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String s = in.nextLine();
boolean matches = Pattern.matches("[HQ9]", s);
System.out.println(matches ? "YES" : "NO");
}
The regular expression .*[HQ9].* does the following: It searches for any characters equal to the ones found inside of the square brackets:
Although someone has already explained the problem (I do not want to take credit from others), here are a few suggestions to reduce and more importantly test your code
import java.util.regex.Pattern;
class Test75B {
public static final String[] TESTS = {
"codeforces",
"Back to Headquarters",
"A cat has nine lives",
"A cat has 9 lives",
"Is it a Query or a Quarry?",
"How Can You Quote 4+5=9!"
};
public static void main(String[] args) {
for (String text: TESTS) {
boolean flag1=false;
String pat1= ".*[HQ9].*";
System.out.println(text);
flag1=Pattern.matches(pat1, text);
System.out.println( flag1 ? "YES" : "NO");
}
}
}
Here is the output I get
codeforces
NO
Back to Headquarters
YES
A cat has nine lives
NO
A cat has 9 lives
YES
Is it a Query or a Quarry?
YES
How Can You Quote 4+5=9!
YES
As an easy test, remove the .* in the regex, recompile and look at the output. You will see they are required.
Related
I'm trying to make a program where a user can post a comment and it'll be able to extract the words, e.g.
I love to #program in #java
would show the output
#program
#java
What I have currently is not running, although there is no errors detected.
class userInput {
public static Scanner input = new Scanner(System.in);
public static String readString(String message){
System.out.println(message);
String readValue = input.nextLine();
return readValue;
}
public static int readInt(String message){
System.out.println(message);
int readValue = input.nextInt();
input.nextLine();
return readValue;
}
public static double readDouble(String message){
System.out.println(message);
double readValue = input.nextDouble();
input.nextLine();
return readValue;
}
public static void close(){
input.close();
}
public static void main(String[] args) {
String post [] = new String [5];
String userPost = "";
userPost = userInput.readString("Type your post");
post[0] = userPost;
String hashtags ="";
for (int i = 0; i<post.length && post[i]!=null;i++){
String[]words = post[i].split(" ");
for(int j=0;j<words.length;j++){
if(words[j].trim().startsWith("#")){
hashtags+=words[j].trim() + " ";
}
}
}
if(hashtags.trim().isEmpty())
System.out.println("No hashtags were typed");
else
System.out.println("Hashtags found:" + hashtags);
}
}
I would use regular expressions.
In the below code, the pattern that I search for is a # character followed by one or more lowercase letters which is what I understood from the example in your question. If that is not the case, then you will need to change the pattern. Refer to the documentation and there are also many questions here about regular expressions in Java.
Also note that the below code uses the stream API. Method results was added in JDK 9, so you need at least that version in order to run the below code.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Comments {
public static void main(String[] strings) {
String sentence = "I love to #program in #java.";
Pattern regex = Pattern.compile("#[a-z]+");
Matcher mtchr = regex.matcher(sentence);
mtchr.results()
.forEach(mr -> System.out.println(mr.group()));
}
}
The above code produces the following output:
#program
#java
You can use split(" ") to split a sentence into words. You can then iterate over all the words and only find those that start with a #. Last but not least you should remove any punctuation marks at the end of words. The most concise and readable way to do this in my opinion is to use Java 8 Streams and the filter() and map() methods. Instead of returning a List using toList() you could of course also return an array using toArray().
import java.util.*;
public class Application {
public static void main(String[] args) {
var sentence = "I love to #program in #java.";
System.out.printf("Hashtags in sentence: %s\n", findHashtags(sentence));
}
public static List<String> findHashtags(String sentence){
var punctuationMarksAtEndOfWordRegex = "[.?,:!]$";
return Arrays.stream(sentence.split(" "))
.filter(word -> word.startsWith("#"))
.map(hashtag -> hashtag.replaceAll(punctuationMarksAtEndOfWordRegex, "")).toList();
}
}
A really naive way is to loop over the comment and check if we encountered a hashtag then once we find a hashtag we start another loop where we add to a our result string the characters starting from the current index until the end of the comment and making sure we don't encounter a space character.
public static String extract(String comment)
{
String result = "";
for(int i=0; i<comment.length(); i++)
{
char current = comment.charAt(i);
if(current == '#')
{
for(int j=i; j<comment.length() && comment.charAt(j) != ' '; j++)
result += comment.charAt(j);
}
}
return result;
}
So basically I have to take these words as an input or hard coded(doesn't really matter). And I have to print what color the word has for example. "Red Dogs"-->Red. And I have two colors red and blue. When its neither I get an extra empty string.
Scanner input=new Scanner(System.in);
String h=System.out.println("Enter a word");
String i=input.next();
public static String color(str r, str b){
for(int i=0;i<=h.length;i++){
if(i="red"){
System.out.println("Red");
}else if(i="blue"){
System.out.println("Blue");
}else{
return("");
}
}
}
practice more.
public static void main(String[] args) {
String colorStr = "RED DOG BLUE BIRD";
System.out.println(color(colorStr));
}
public static String color(String colorStr) {
Set<String> set = new HashSet<>(Arrays.asList("RED", "BLUE"));
StringBuilder presentColorStr = new StringBuilder();
String[] words = colorStr.split(" ");
for (String word : words) {
if(set.contains(word)) {
presentColorStr.append(word).append(" ");
}
}
return presentColorStr.toString();
}
Looks like you are entirely new to Java code. I will explain few things about your code.
Conditinal construct if..else accept a boolean literal only.
if(a = b) // this is error as = is assignment operator and will not return boolean unless you assign a boolean
if(a == b) // this is right approach to compare two values.
Comparison of two reference is different than values. Ex. String holds reference so you cannot compare two string with == . You must compare two Strings with equals method that returns boolean if both string are same.
String str1 = "hello";
String str2 = "hello";
if(str1.equals(str2)) {
System.out.println("both are same.");
}
Further, your requirement to check if input string contains a string can be done using String.contains() function
String str1 = "Red Ball";
String str2 = "ball";
if(str1.contains(str2)) {
System.out.println("String conatins str2");
}
You can also use methods toLowerCase() and toUpperCase() to make it case independent.
So here is the part of my code:
if (file.toString().??? && file.toString().endsWith(FilterCommand.afterDot)) {
System.out.println(file.toAbsolutePath());
User will enter string, something like this(sometext.txt is just an example of one input, user will input several times and every time it can be something different): sometext.txt and my job is to find all files which match given expression. In this example it may be something like this:
sometext.txt
sometHhBkJnKext.txt
sometANYTHINGCANBEHEREext.txt
So "somet" and "ext.txt" remains constant. In between them anything can be there. I mean 0 or more characters. We can also assume that user will never input two *. It will always be one * and it can be at front, in the middle or in the end.
I am able to separate given string on string before dot(somet*ext, I save it in variable FilterCommand.beforeDot) and after dot(txt, I save it in variable FilterCommand.afterDot). So, in if I need to ask if the text after dot is same (I use:file.toString().endsWith(FilterCommand.afterDot) and if the text before dot match given expression. How can I do it?
So i think you can just do something like this -
if(file.toString().matches("somet.*ext\\.txt")){
System.out.println(file.toAbsolutePath());
}
else{
System.out.println("Not matching");
}
You can check it like this (This will also match the .txt so no need to split the filename):
public static void main(String[] args) {
if(Pattern.matches("somet.*ext\\.txt", "somet**HhBkJnK**ext.txt"))
{
System.out.println("Yes");
}
else
{
System.out.println("No");
}
if(Pattern.matches("somet.*ext\\.txt", "sometext.txt"))
{
System.out.println("Yes");
}
else
{
System.out.println("No");
}
if(Pattern.matches("somet.*ext\\.txt", "some**sdfsdfsdft**ex.txt"))
{
System.out.println("Yes");
}
else
{
System.out.println("No");
}
}
Output:
Yes
Yes
No
Just do this to check with your file:
if(Pattern.matches("somet.*ext\\.txt", file.toString()))
{
System.out.println("Yes");
}
else
{
System.out.println("No");
}
Firstly, you need to escape the dot, i.e. \. otherwise the regex parser will interpret the dot as 'find a single character, any character'.
For example:
public static void main(String args[]) {
String regexFilePattern = "[[a-zA-Z0-9]+]\\.[[a-zA-Z0-9]+]";
Matcher matcher = null;
for(int i = 0; i < args.length; i++) {
matcher = Pattern.compile(regexFilePattern).matcher(args[i]);
while (matcher.find()) {
if (matcher.start() > 0) {
//there is a match!
//manipulate the result here when the text after the dot
//matches the text before the dot
}
}
}
}
I'm not sure why you would need to split the string that the user provides you at the '.'. It seems like you could just write file.toString().matches(userString)to determine if that file matches the provided pattern
gets a single letter from the user. This method validates that it’s either a valid letter or the quit character, ‘!’. It'll eventually keep asking for characters, then once the user is done, they'll type ‘!’ to make the loop end and move on to printing their list of chars
public static String isValidLetter(){
char[] charArray;
charArray = new char[11];
charArray[0] ='C';
charArray[1] ='E';
charArray[2] ='F';
charArray[3] ='H';
charArray[4] ='I';
charArray[5] ='J';
charArray[6] ='L';
charArray[7] ='O';
charArray[8] ='P';
charArray[9] ='S';
charArray[10] ='T';
charArray[11] ='U';
String input;
char letter;
Scanner kb = new Scanner(System.in);
System.out.println("Enter a single character: ");
input=kb.nextLine();
letter = input.charAt(0);
Reading the strings from console.. type "a", enter, "b", enter, "!", enter
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
Scanner scann = new Scanner(System.in);
List<String> letterWords = new LinkedList<String>();
String str = null;
while (!"!".equals(str)) {
str = scann.next();
letterWords.add(str);
}
for (String word : letterWords) {
System.out.println(word);
}
scann.close();
}
}
If you just want to have a "collection" of valid characters, then you also could use a String instead of an array. It would be much easier to search in it and it avoids errors like in your example (you've initialized your array with size of 11, but you're inserting 12 elements):
public static boolean isValidLetter(final char character) {
final String validCharacters = "CEFHIJLOPSTU";
return validCharacters.contains(String.valueOf(character));
}
This method expects a single char and returns true if it is valid, false otherwise. Please mind, that this check is case sensitive.
You could use that method like this:
final Scanner scan = new Scanner(System.in);
String input;
while (!(input = scan.nextLine()).equals("!")) {
if (!input.isEmpty() && isValidLetter(input.charAt(0))) {
// ... store valid input
System.out.println("valid");
}
}
This loop requests user input until he enters !. I've omitted the storing part. It is up to you to do this last part.
Modify your isValidLetter method to return boolean.
Modify your isValidLetter method to get a char as a parameter.
In isValidLetter, try to find a letter by using a helper function, something like:
static boolean contains(char c, char[] array) {
for (char x : array) {
if (x == c) {
return true;
}
}
return false;
}
Somewhere in your code where you need the input (or in main for testing), ask for user input (as you already did in isValidLetter). Perform a loop, asking for input, until it is right, or until it is your ending character.
I am not posting the complete solution code on purpose, as it is better for you to play with the code and learn. I only gave directions on how to try; of course it is not the only way, but it fits with what you've already started.
I wanted to take a String using Scanner.next() and see if it contains a number or not. I used regex to check if a string contains anything but a number. The regex works correctly if the string is hard coded, but not when taken from keyboard. I expected input of 5 to be detected as a number, but it is not. Please tell me why. My code:
import java.util.Scanner;
public class Error {
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
int num = 0;
String input = "";
boolean isStringNumber = true;
System.out.println("\nPlease enter a number only...");
input = inp.nextLine();
isStringNumber = input.contains("[^0-9]+");
if (isStringNumber == false) {
System.out.println("\nYou entered a non number " + input);
}
}
}
contains uses a String literal as its argument. Use matches instead
isStringNumber = input.matches("[0-9]+");
or simply
isStringNumber = input.matches("\\d+");
BTW: Scanner has a nextInt method for accepting integer values
instead isStringNumber = input.contains("[^0-9]+");
try isStringNumber = input.matches("[0-9]+");