-2

How to use regex to match a string that could only contain 17 alphanumerical characters and does not contains the letter 'q' 'o' and 'i'. aka, only letters and numbers but not 'q' 'o' and 'i'.

Two conditions can be done in python separately:

  1. [a-z0-9]{17}
  2. [^qoi]

So except specifying valid character interval or putting two conditions together using AND is there any way more elegant in python that you can actually specify the character that you want to include while excluding the ones that you do not want as such [a-z0-9&&[^qoi]] in Java

(for example, there are 10 random letters that I want to exclude, it would be very tedious to specify each interval [a-bd-eh-ow-......]

If there is no such way, I have only to accept the reality of python regex as it is.

Appreciate your help! Erik

Alejandro Galera
  • 3,445
  • 3
  • 24
  • 42
Erik.Z
  • 57
  • 1
  • 7
  • @Ken White so 'a' ' 'b' 'c' is just an example , for demo I mean , it could be any number of arbitrary letters in the class, so I am looking for a elegant general approach , thanks ! – Erik.Z Aug 19 '17 at 01:33
  • Can you show a realistic example then, please? – Ry- Aug 19 '17 at 01:33
  • @Ryan I have added in the original questions :) – Erik.Z Aug 19 '17 at 01:36
  • Does it need to be one regular expression, or can you do one check for `^[a-z0-9]{17}\Z` and one check for `[qoi]`? – Ry- Aug 19 '17 at 01:51
  • @Ryan I am looking for regular expression solution , so to include the two condtions in one single regx , thanks! – Erik.Z Aug 19 '17 at 02:44
  • 1
    `(?![^q]*[qoi])^[a-z0-9]{17}\Z` enjoy – Ry- Aug 19 '17 at 02:45
  • @KenWhite I dont appreciate your time and answer , sorry If I didnt make myself clear and I did not reject your answer and you dont have to delete it.... again I am sorry if I did't make the question clear, appreciate your help! – Erik.Z Aug 19 '17 at 04:10
  • @Ryan Amazing!!!Exactly What I am looking for !! very elegant! thank you!:) – Erik.Z Aug 19 '17 at 04:49
  • @Ryan Can I ask how does this part:(?![^q]*[qoi]) works? I know it is to exclude the letter 'q' 'i' 'o' ,but I am not sure what the syntax means .... thank you! – Erik.Z Aug 19 '17 at 05:39
  • It’s a [negative lookahead](https://stackoverflow.com/questions/2973436/regex-lookahead-lookbehind-and-atomic-groups). If the string starts with any number of characters that are not q (`[^q]`) and then a `q`, `o`, or `i` (`[qoi]`), the entire match fails (`?!`). This could actually be simplified by replacing `[^q]` with `.` since the other part of the match doesn’t allow newlines anyway. `(?!.*[qoi])^[a-z0-9]{17}\Z` – Ry- Aug 20 '17 at 01:40
  • @Ryan thank you so much! You are a Legend!:) – Erik.Z Aug 20 '17 at 12:05

2 Answers2

2

you can put anything you want in square brackets. So, for example, to match any letter except q, o, and i, you can use this:

[0-9abcdefghjklmnprstuvwxyz]

You can also specify multiple ranges which might make it more obvious which characters you are skipping:

[0-9a-hj-npr-z]

There are perhaps more elegant ways to do it, but the basic concept is the same: put only the characters you want to match inside [].

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
1

Here are two options:

Check each condition separately

Use two regular expressions and ensure they both match. This is most like your java example.

import re
test_case = "asdFghijalkdjflkjsd"
re.match("^[A-Za-z0-9]{17}$", test_case) and re.match("^[^qoi]+$", test_case)

Explicitly list what's legal

List all legal alphanumeric characters, which should exclude q, i, and o

import re
test_case ="12345a78901234567"
re.match("^[ABCDEFGHJKLMNPRSTUVWXYZabcdefghjklmnprstuvwxyz0-9]{17}$", test_case)

Of course, this can be condensed using ranges, such as A-HJ-NPR-Z, etc.

drootang
  • 2,351
  • 1
  • 20
  • 30