Regular Expressions with Java Patterns

Asked

Viewed 615 times

2

I need to do a college exercise, which is this: Validate with regular expressions any word that contains exactly two characters 'a' and two characters 'b' or more. I made the following expression in class Pattern:

Pattern pattern = Pattern.compile("a{2}b{2,}");

That one Pattern only validates expressions starting with two characters 'a' and then two or more 'b'. However, the exercise requires that the two characters can be anywhere in the sentence and not necessarily at the beginning, as well as the characters 'b'. How do I make that expression regular

  • .*a{2}b{2,}.* see if it fits.

  • It did not work because it did not validate the string "Babba", and in this exercise, this string would be valid

6 answers

1

Use a Lookahead positive.

(?=padrão)

A Lookahead allows checking whether the group can be found by starting at the position it is in, but without capturing or advancing the reading of the string being analyzed. This way you can check if there are two conditions in the same expression.

For example, to check whether a string contains at least one character "a" and a character "b":

^(?=.*a).*b


Regular expression

^[^ab]*+(?=(?:[^b]*b){2})(?:[^a]*a){2}[^a]*$

Online example


Meaning

  • ^[^ab]*+ - Optional characters that are not a nor b at the beginning of the string.
  • (?=(?:[^b]*b){2}) - Lookahead to check for two b, no further progress on string reading.
  • (?:[^a]*a){2}[^a]*$ - Matches exactly two characters a until the end of the string, but no more than two.


Code

import java.util.regex.Matcher;
import java.util.regex.Pattern;
final String regex = "^[^ab]*+(?=(?:[^b]*b){2})(?:[^a]*a){2}[^a]*$";

String[] exemplos = new String[] { 
    "---aabb+++", "---bbaa+++", "---abab+++", "---baba+++",
    "---babba++", "---bbbbbaa", "ababbb++++", "ccabcab+++",
    "----bcdbaa", "-ababd++++", "bbbaabbbbb", "bbbabbbbbb",
    "bbbaaabbbb", "baaaaaaaaa", "abbbbbbbbb", "ccacbcacbc"
};


final Pattern pattern = Pattern.compile(regex);

for (String palavra : exemplos) {
    Matcher matcher = pattern.matcher(palavra);

    if (matcher.find()) {
        System.out.println(palavra + " ✔️");
    } else {
        System.out.println(palavra + " ✖️️");
    }
}

Upshot

---aabb+++ ✔️
---bbaa+++ ✔️
---abab+++ ✔️
---baba+++ ✔️
---babba++ ✔️
---bbbbbaa ✔️
ababbb++++ ✔️
ccabcab+++ ✔️
----bcdbaa ✔️
-ababd++++ ✔️
bbbaabbbbb ✔️
bbbabbbbbb ✖️️
bbbaaabbbb ✖️️
baaaaaaaaa ✖️️
abbbbbbbbb ✖️️
ccacbcacbc ✔️

Online example

1

What you want is a check.

The rule says, contain :

  • 2 characters a
  • 2 characters b or more

Note that in the b the "or more" part is irrelevant because if you have 2 b is already valid.

Resolution

(a.*){2}b.*b|(b.*){2}a.*a|(a.*b|b.*a){2}

See working in REGEX101.

Explanation

  • (a.*){2}b.*b search for sentences that have a followed by a, after b followed by b.
  • (b.*){2}a.*a search for sentences that have b followed by b, after a followed by a.
  • (a.*b|b.*a){2} quest a followed by b or b followed by a.
  • 1

    But if the string is ccabcab he does not identify

0


Solved. I used the following Pattern:

Pattern pattern = Pattern.compile("(bbb*ab*ab*)|(babb*ab*)|(baabb*)|(ababb*)|(aabbb*)|(abbb*ab*)");
  • 1

    Your Pattern failure in some cases such as "bcdbaa" or "ababd". Take a look at mine reply.

0

Try the pattern ^((.*[^a])?[a]{2}[b]{2,}.*)$.
Explanation:
- The ^ at the beginning and the $ at the end of the force the full recognition of the string.
- The pattern (.*[^a]) avoids grouping more than two a, and the ? allows the [a]{2}[b]{2,} either at the beginning of the string.
- The pattern [a]{2}[b]{2,} does the desired recognition.
- The pattern .* at the end completes the string.

0

Try the following:

Pattern pattern = Pattern.compile("(?=^[.[^a]]*?a[.[^a]]*?a[.[^a]]*?$)^.*?b.*?b.*$");
//Use o find ou invés de matches
System.out.println(pattern.matcher("abdbbbabd").find());    //true
System.out.println(pattern.matcher("abdbbbbd").find());     //false

-1

I suggest the following regular expression:

Pattern pattern = Pattern.compile("(aa|bb)");

See the test online.

  • This expression did not work for the exercise, because this regex only validates the presence of "aa" or "bb", and I need to validate words that have exactly two a anywhere in the word and 2 or more b anywhere in the word as well

  • I tried the following regex "( a { 2 } | b { 2 , } )" but it did not validate the word "babab"

Browser other questions tagged

You are not signed in. Login or sign up in order to post.