Java Regex Missing a Match - java

I'm trying to return a string of regular expression matches. Specifically, trying to return all vowels (aeiou) found in a string. The following code returns the 2 oo's but not the e.
Expecting: eoo
Getting: oo
Why is it not finding and appending the e to the StringBuilder object? Thank you.
import java.lang.StringBuilder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main {
public static void main(String[] args) {
String inp = "Hello World!";
System.out.println(vowelOnly(inp));
}
public static String vowelOnly(String input) {
Pattern vowelPattern = Pattern.compile("[aeiou]+");
Matcher vowelMatcher = vowelPattern.matcher(input);
StringBuilder sb = new StringBuilder();
int i = 0;
if (vowelMatcher.find()) {
while (vowelMatcher.find( )) {
sb.append(vowelMatcher.group());
i++;
}
return sb.toString();
} else {
return "No matches";
}
}
}

When you call vowelMatcher.find() inside your if condition, you tell the matcher to find the first string matching the specified pattern. In this case, it is "e". When you call it again in your while condition, the matcher finds the next match, in this case it is "o".
From there, it loops through the rest of the String. If you gave it the input "Hello World eeee", it would return "ooeeee", since you always discard the first match by calling .find() without calling .group() immediately after.
Change your loop to be like this, and it should work:
int i = 0;
while (vowelMatcher.find()) {
sb.append(vowelMatcher.group());
i++;
}
return i == 0 ? "No matches" : sb.toString(); // return "no matches" if i is 0, otherwise, string

Your first call to vowelMatcher.find() in the if statement finds the "e" and the subsequent calls to vowelMatcher.find() in the while loop find all subsequent vowels.

Thats what you need:
public static void main(String[] args) {
String inp = "Hello World!";
System.out.println(vowelOnly(inp));
}
public static String vowelOnly(String input) {
Pattern vowelPattern = Pattern.compile("[aeiou]+");
Matcher vowelMatcher = vowelPattern.matcher(input);
StringBuilder sb = new StringBuilder();
int i = 0;
while (vowelMatcher.find()) {
sb.append(vowelMatcher.group());
i++;
}
return i == 0 ? "No matches" : sb.toString();
}

That would probably be the solution you're looking for:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String inp = "Hello World!";
System.out.println(vowelOnly(inp));
}
public static String vowelOnly(String input) {
Pattern vowelPattern = Pattern.compile("[aeiou]+");
Matcher vowelMatcher = vowelPattern.matcher(input);
StringBuilder sb = new StringBuilder();
while (vowelMatcher.find()) {
sb.append(vowelMatcher.group());
}
if (sb.length() == 0) {
return "No matches";
}
return sb.toString();
}
}
Couple of notes:
You don't need to import java.lang.* classes.
With the matcher, whatever you find, you should group it immediately to collect.
You don't need the iteration variable. StringBuilder.length() would simply reveal if it's empty.

Related

Invalid result from coderbyte

Refer to the test below, some test cases are failed in fact even the output is correct. Can anyone advise?
https://coderbyte.com/editor/Longest%20Word:Java
Longest Word
Have the function LongestWord(sen) take the sen parameter being passed and return the largest word in the string. If there are two or more words that are the same length, return the first word from the string with that length. Ignore punctuation and assume sen will not be empty.
Examples
Input: "fun&!! time"
Output: time
Input: "I love dogs"
Output: love
Below are the invalid failing test cases
For input "a beautiful sentence^&!" the output was incorrect. The correct output is beautiful
For input "oxford press" the output was incorrect. The correct output is oxford
For input "123456789 98765432" the output was incorrect. The correct output is 123456789
For input "a b c dee" the output was incorrect. The correct output is dee
For input "a confusing /:sentence:/[ this is not!!!!!!!~" the output was incorrect. The correct output is confusing
The program
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main {
public static final String REG_EXP_CHAR_ONLY = "(?=.*?[a-zA-Z0-9 ])";
public static String LongestWord(String sen) {
StringBuffer strBuffer = new StringBuffer();
for (String c : sen.split("")) {
//System.out.println("c--------->" + c);
if (isValid(c)) {
strBuffer.append(c);
}
}
//System.out.println(strBuffer.toString());
String longest = Arrays.stream(strBuffer.toString().split(" ")).max(Comparator.comparingInt(String::length))
.orElse(null);
return longest;
}
public static boolean isValid(String c) {
// System.out.println("char -->" + c);
Pattern pattern = Pattern.compile(REG_EXP_CHAR_ONLY);
Matcher matcher = pattern.matcher(c);
boolean matchFound = matcher.find();
if (matchFound) {
// System.out.println("Match found");
return true;
}
return false;
}
public static void main (String[] args) {
// keep this function call here
Scanner s = new Scanner(System.in);
System.out.print(LongestWord(s.nextLine()));
}
}
It seems that this is a problem from coderbyte. I copied your code and submitted. Then it passed.
==================================================================
Edit:
maybe you should use "StringBuilder"(not StringBuffer) instead.
I just fixed all warnings in ide and then all tests pass.
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main {
public static final String REG_EXP_CHAR_ONLY = "(?=.*?[a-zA-Z0-9 ])";
public static String LongestWord(String sen) {
StringBuilder strBuffer = new StringBuilder();
for (String c : sen.split("")) {
//System.out.println("c--------->" + c);
if (isValid(c)) {
strBuffer.append(c);
}
}
return Arrays.stream(strBuffer.toString().split(" ")).max(Comparator.comparingInt(String::length))
.orElse(null);
}
public static boolean isValid(String c) {
// System.out.println("char -->" + c);
Pattern pattern = Pattern.compile(REG_EXP_CHAR_ONLY);
Matcher matcher = pattern.matcher(c);
// System.out.println("Match found");
return matcher.find();
}
public static void main (String[] args) {
// keep this function call here
Scanner s = new Scanner(System.in);
System.out.print(LongestWord(s.nextLine()));
}
}

grab last four digits approach after deleting non digits using regex

I'm getting the URL(http://localhost:8080/CompanyServices/api/creators/2173) shown below from a HTTP Response header and I want to get the id after the creators which is 2173.
So, I deleted all non digits as shown below and got the following result : 80802173.
Is it a good approach to get the last 4 digits from the above set of digits?
One thing is that, this part localhost:8080 could change depending upon the server I deploy my application so I'm wondering if I should just grab something after creators/ ? If yes, then what is the best way to go about it?
public class GetLastFourIDs {
public static void main(String args[]){
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
String replaceString=str.replaceAll("\\D+","");
System.out.println(replaceString);
}
}
You can use regex API e.g.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
Pattern pattern = Pattern.compile("(creators/\\d+)");
Matcher matcher = pattern.matcher(str);
int value = 0;
if (matcher.find()) {
// Get e.g. `creators/2173` and split it on `/` then parse the second value to int
value = Integer.parseInt(matcher.group().split("/")[1]);
}
System.out.println(value);
}
}
Output:
2173
Non-regex solution:
public class Main {
public static void main(String[] args) {
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
int index = str.indexOf("creators/");
int value = 0;
if (index != -1) {
value = Integer.parseInt(str.substring(index + "creators/".length()));
}
System.out.println(value);
}
}
Output:
2173
[Update]
Incorporating comment by Andreas as follows:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
Pattern pattern = Pattern.compile("creators/(\\d+)");
Matcher matcher = pattern.matcher(str);
int value = 0;
if (matcher.find()) {
value = Integer.parseInt(matcher.group(1));
}
System.out.println(value);
}
}
Output:
2173

Loop Through a String and return just one character in Java

so I'm developing this Java program which I need to iterate through a string of character and I just want to return back a character in which it contains (F or f or S or s or B or b or or L or l) in which if there is duplicate of the character found in the string it just take take ealiest character found. I'm just a beginner so please help me. this is what I can have so far. Thanks for your time
command ="France";
public static char CommandRestrictor (String command)
{
for(int i=0; i<command.length();i++)
{
char result=command.charAt(i); //set variable character char_bin to binary value in place of i
if(result=='F'||result=='f'||result=='L'||result=='l'||result=='S'||result=='s'||result=='B'||result=='b'||result=='r'||result=='R') {
return ;
}
else {
return 'f';
}
}
return result;
}
input result: "France";
output result: 'F'
Your result variable is instantiated within the for loop, and so it is only accessible within the for loop. I would suggest the following:
public static char CommandRestrictor (String command)
{
char result = 'f';
for(int i = 0; i < command.length(); i++)
{
if(command.charAt(i)=='F'||command.charAt(i)=='f'||
command.charAt(i)=='L'||command.charAt(i)=='l'||
command.charAt(i)=='S'||command.charAt(i)=='s'||
command.charAt(i)=='B'||command.charAt(i)=='b'||
command.charAt(i)=='r'||command.charAt(i)=='R')
{
result = command.charAt(i);
break;
}
}
return result;
}
EDIT: Silly mistake. My if loop conditions said result=='F' rather than command.charAt(i)=='F'.
Do it as follows:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String[] testStrs = { "A football", "A Football", "A lamp", "A ball", "A Ball" };
for (String str : testStrs) {
System.out.println(commandRestrictor(str));
}
}
public static char commandRestrictor(String command) {
char ch = '\0';
Pattern pattern = Pattern.compile("[FfSsBbLl]");
Matcher matcher = pattern.matcher(command);
if (matcher.find()) {
ch = command.charAt(matcher.start());
}
return ch;
}
}
Output:
f
F
l
b
B

Need help to transform the code for removing punctuation from Java string into recursion

I have come up with a solution for removing punctuation from a String in Java.Need to convert this into a recursive method.I would be thankful if someone can help me to solve this.
The code is as below:
public class punctuationRemove {
//private static String punc = "[][(){},.;!?<>%]";
static StringBuilder sb = new StringBuilder();
static char[] punc = "',.;!?(){}[]<>%".toCharArray();
public static void main(String[] args){
String s = "Hello!, how are you?";
System.out.println(removePuntuation(s));
}
public static String removePuntuation(String s)
{
String tmp;
boolean fl=true;
for(int i=0;i<s.length()-1;i++)
{
fl=true;
char strChar=s.charAt(i);
for (char badChar : punc)
{
if (badChar == strChar)
{
fl=false;
break;
}
}
if(fl)
{
sb.append(strChar);
}
}
return sb.toString();
}
}
Recursion usually has two parts to it:
A base case in which all recursion stops and a result is returned, and
An iterative step in which recursion continues.
How does one recursively examine each character of a String? They only look at the first character and send the substring from 1 to the end of it off to a recursive call.
As an example:
public String splitRecursive(String s) {
if(!s.isEmpty()) {
return s.charAt(0) + splitRecursive(s.substring(1));
} else {
return "";
}
}
Let's think about that for a moment - so long as the string isn't empty (i.e. base case), then I should take the first character I get and append that to the result of another call (i.e. iterative step), which takes the substring from 1 to however many characters are left. If it is empty, I just return the empty string.
This skeleton piece of code is actually 3/4ths of what you need to work out your problem. You need to augment it to insepct the character to see if it is one of your punctuation characters you've already isolated.
Consider your iterative step: if you see punctuation, what should you do? If you don't see punctuation, what should you do? I leave the rest as an exercise to the reader.
I think this would help you,
public class RemovePunctuations {
public static int i = 0;
public static void main(String[] args){
String s = "Hello!, how are you?";
System.out.println(removePuntuation(s));
}
Using Recursion,
public static String removePuntuation(String s){
char [] charArray = s.toCharArray();
if(!Character.isLetter(charArray[i]) && !Character.isSpaceChar(charArray[i])){
s = s.replace(String.valueOf(charArray[i]), "");
i--;
}
i++;
if(i<s.length())
return removePuntuation(s);
return s;
}
}
You can get the same result from the following way without using recursion,
public static String removePuntuation(String s){
char [] charArray = s.toCharArray();
for (int i = 0; i < charArray.length; i++) {
if(!Character.isLetter(charArray[i]) && !Character.isSpaceChar(charArray[i])){
s = s.replace(String.valueOf(charArray[i]), "");
}
}
return s;
}

Java Pattern/Matcher - Return the matches from one method to another

I'm an absolute Java beginner. I've searched on the forums, but couldn't find an answer to this question.
I have two classes, one which browses through an arraylist of sentences. I only attach the for-each loop as seen below.
"matching" is the instance of the other class (containing the pattern/matcher code)
matchEndings is the method, attached below.
for (String sentence: sentences) {
String match = matching.matchEndings(sentence);
if (match.length() > 0) {
System.out.println(match);
}
}
This is the method.
public String matchEndings(String s){
Pattern p = Pattern.compile(".*?(aa|ee)");
Matcher m = p.matcher(s);
return m.group();
}
My question is, how do I return the matched sentences, containing aa / ee endings, to the first class, and have it printed there? The code is compiled, but when I run I get
Exception in thread "main" java.lang.IllegalStateException: No match found
at java.util.regex.Matcher.group(Unknown Source)
at java.util.regex.Matcher.group(Unknown Source)
Thank you so much in advance!
Matcher.group() only returns if there is a match already. You need to do something like this:-
if (m.matches()) {
return m.group();
} else {
return "";
}
It seems like overkill to use RegEx when all you need is a simple endsWith(String):
public void print(final List<String> sentences, final String... endings){
for(final String sentence : sentences){
for(final String ending : endings){
if(sentence.endsWith(ending)){
System.out.println(sentence);
break;
}
}
}
}
The method above will loop through a List<String> of sentences and print out all of the sentences that end with one of the elements in endings. For usage, you could try:
print(sentences, "aa", "ee");
Where sentences is your ArrayList<String> of sentences.
The matches or find methods must precede the group method. Since matches attempts to match the entire region against the pattern, it is more appropriate here
public String matchEndings(String s){
Pattern p = Pattern.compile("(aa|ee)$");
Matcher m = p.matcher(s);
if (m.matches) {
return m.group();
} else {
return ""
}
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PotenssienSumma {
public static void main(String[] args) {
ArrayList<String> sentences = new ArrayList<>(10);
sentences.add("aa");
sentences.add("1324");
for (String sentence: sentences) {
String match = Matching.matchEndings(sentence);
if (match.length() > 0) {
System.out.println(match);
}
}
}
}
class Matching{
public static String matchEndings(String s){
Pattern p = Pattern.compile(".*?(aa|ee)");
Matcher m = p.matcher(s);
if (m.matches()) {
return m.group();
} else {
return "";
}
}
}
Don't construct Pattern in the method. That is expensive. Put the pattern object into a static final variable.
The correct use for patterns is the following:
while(matcher.find()) {
sysout(matcher.group());
}
This will print all matches, if you want just one match, replace the while with if.
I don't know if this is intentional but your regex doesn't match ee|aa to end of the string. It matches ee or aa anywhere in the string along with any characters preceeding it. For instance for string Fox preens in front of a vixen your regex returns string Fox pree. Don't know if that's intended.
Here's a class that takes a list or a collection of strings as an argument and then lazily finds all words that end in aa or ee. It has a main method you can run to test.
public class Endings implements Iterable<String> {
private final Iterable<String> strings;
private static final Pattern pat = Pattern.compile("(?<=^|\\s)\\S*(aa|ee)(?=\\s|$)");
public static void main(String[] args) {
Endings endings = new Endings(Arrays.asList("This testaabb testee testaa", "Test2aa Test3ee ", "no match"));
for(String word : endings) {
System.out.println(word);
}
}
public Endings(Iterable<String> strings) {
this.strings = strings;
}
public Iterator<String> iterator() {
return new Iterator<String>() {
private Iterator<String> iter = strings.iterator();
private Matcher m;
private String result;
public boolean hasNext() {
if (result == null) {
if (m == null) {
if (iter.hasNext()) {
m = pat.matcher(iter.next());
} else {
return false;
}
}
if (m.find()) {
result = m.group();
return true;
} else {
m = null;
return hasNext();
}
} else {
return true;
}
}
public String next() {
if (result != null) {
String ret = result;
result = null;
return ret;
} else {
throw new NoSuchElementException();
}
}
public void remove() {
}
};
}
}

Categories