I'm trying to write a regular expression which doesn't allow 'a' and 'c' to be next to each other in any combination of "abc" , the combinations might be "a" , "b" , "c" , "acb" , "abac" , here "abac" must be ignored because it contains "a" and "c" next to each other , I've written a regular expression which is doing half the job correct and the other half incorrect , it's basically ignoring a , bcb , bcc and others which are not supposed to be ignored.
Here's the regular expression :
^(a?b)*c?$
Here's the output I'm getting :
[a, b, c, ba, ca, ab, cb, ac, bc, baa, caa, aba, cba, aca, bca,
bab, cab, abb, cbb, acb, bcb, bac, cac, abc, cbc, acc, bcc]
b
c
ab
bc
bab
abb
abc
Could someone please tell me what I'm doing wrong ?
CodePudding user response:
Here is a much simpler straightforward regex. Rather than thinking to exclude the pattern, you can also match the pattern and ignore them like following example:
String[] str = {
"a", "b", "c", "ba", "ca", "ab", "cb", "ac", "bc", "baa",
"caa", "aba", "cba", "aca", "bca", "bab", "cab", "abb",
"cbb", "acb", "bcb", "bac", "cac", "abc", "cbc", "acc", "bcc"
};
for(int i=0; i<str.length; i) {
if(str[i].matches("ac.?|.?ac|ca.?|.?ca")) {
System.out.println("MATCH: " str[i]);
} else {
System.out.println(str[i]);
}
}
This makes the following output:
a
b
c
ba
MATCH: ca
ab
cb
MATCH: ac
bc
baa
MATCH: caa
aba
cba
MATCH: aca
MATCH: bca
bab
MATCH: cab
abb
cbb
MATCH: acb
bcb
MATCH: bac
MATCH: cac
abc
cbc
MATCH: acc
bcc
CodePudding user response:
Your expression ignores several cases:
- anything with more than one
c
is ignored - anything with
a
orb
coming afterc
is ignored (that means if there is ac
that has to be the last character) - anything containing an
a
is ignored if it doesn't contain also ab
after thata
- each
a
must be followed by ab
- also your grouping is probably not really the form you need. You should use
(?:X)
for a non capturing group.
I would suggest a regex like
^(?:(?:a(?!c))?b?c?) $
This matches all a
s not followed by a c
and also all b
s and c
s - and needs at least one occurence so that empty strings are not matched.
You can play with it and get detailed explanations at https://regex101.com/r/DoyUPG/1
CodePudding user response:
In spite of your provided data, you said "the combinations might be "a" , "b" , "c" , "acb" , "abac" , here "abac"
which indicates they could be more than just three letters. Rather than use a regex
I recommend String.contains
.
String[] str = { "a", "b", "c", "babbacb", "ca", "ab", "cb",
"aeseac", "bc", "baa", "caa", "aba", "cba", "aca",
"bca", "bab", "cab", "abb", "cbbabcda", "acb",
"bcbacbae", "bacadbac", "adecdcac", "abc", "cbc",
"acc", "adbbcc", "abac" };
for (String s : str) {
if (!(s.contains("ac") | s.contains("ca"))) {
System.out.println(s);
}
}
prints
a
b
c
ab
cb
bc
baa
aba
cba
bab
abb
cbbabcda
abc
cbc
adbbcc
But if you want to use a regex
then simply check for those strings that
matches string that is composed of at least one ac
or ca
.
String regex = ".*((ac)|(ca)).*";
for (String s : str) {
if (!s.matches(regex)) {
System.out.println(s);
}
}
prints the same as above.