Home > Enterprise >  Oracle REGEXP confusion
Oracle REGEXP confusion

Time:07-22

Question: Query the list of CITY names from STATION that do not start with vowels and do not end with vowels. Your result cannot contain duplicates.

Solution I tried but failed (giving incorrect output):

SELECT DISTINCT city FROM station
WHERE NOT REGEXP_LIKE(city, '^(a|e|i|o|u).*(a|e|i|o|u)$','i');

Solution which worked:

SELECT DISTINCT city FROM station
WHERE REGEXP_LIKE(city, ^[^aeiou].*[^aeiou]$,'i');

Please can anyone explain why the first solution is failing.

CodePudding user response:

The first version logically says to not find cities which begin and end with vowels. However, it leaves open the possibility for a city which starts with a vowel, but does not end with a vowel. It also admits cities which do not start with a vowel, but end with a vowel. The second version only allows cities which start and end with no vowel letters.

As a side note, the regex in your first version would better be written as:

SELECT DISTINCT city
FROM station
WHERE NOT REGEXP_LIKE(city, '^[aeiou].*[aeiou]$', 'i');

That is, use the character class in square brackets rather than an alternation of single letters (though your alternation was correct, just slightly awkward).

CodePudding user response:

Can you explain how I can fix my first code only for the required result, instead of using the second code, just out of curiosity.

In boolean logic (NOT A AND NOT B) = NOT (A OR B) so if is A is "starts with a vowel" and B is "ends with a vowel" then you want to find the values where it does not either start or end with a vowel:

Which could be:

SELECT DISTINCT city
FROM   station
WHERE  NOT (  REGEXP_LIKE(city, '^(a|e|i|o|u)','i')
           OR REGEXP_LIKE(city, '(a|e|i|o|u)$','i') );

or, as a single regular expression:

SELECT DISTINCT city
FROM   station
WHERE  NOT REGEXP_LIKE(city, '^(a|e|i|o|u)|(a|e|i|o|u)$','i');

Note: you can replace (a|e|i|o|u) with [aeiou].

  • Related