Regex Lookahead matching arbitrary number of characters

Viewed 56

This is similar to Regex to match a word containing all of specified characters but not exactly, as I am trying to find a more concise method. I have read through the Regex Wiki, and have been working in regex101.com to develop this.

I'm writing a regular expression to match a 5 letter word from a list of words in a known format (no special characters, all lowercase letters, no spaces, all characters can be matched with [a-z]). I know how to use a lookahead to determine if a word contains a letter:

import re
re.compile("(?=\S*[a])(?=\S*[h])(?!.*[dieuoftrm])al[^a]..")
            ^^^^^^^^^^ -------------------------------------Word contains an A
                      ^^^^^^^^^^----------------------------Word contains an H
                                ^^^^^^^^^^^^^^^^------------Word does not contain any of  dieuoftrm
                                                

However, using this method of positive lookaheads, I have to add a new lookahead for each letter I want contained in the word (i.e, I have to add another (?=\S*[a]) for each letter I want).

Similar to the negative lookahead, where all unwanted letters are contained in a single set, is there a way to do this with the positive lookahead?

I've experimented using regex101.com and found a few ways that do not work. One such approach I tried is using a set similar to the negative lookahead.

The following expressions are trying to match alpha given the following clues:

  • The word begins with al
  • The 3rd letter (1-based indexing) is NOT an a
  • The word contains both an a and h.
  • The letters dieuoftrm do not appear anywhere in the word.
#This one fails due to the lookahead looking for EITHER an a or h in the word. 
>>> re.compile("(?=\S*[ah])(?!.*[dieuoftrm])al[^a]..")

#This one fails due to looking for either `ah` or `ha` in the word. 
#The letters can appear anywhere in the word
>>> re.compile("(?=\S*[ah])(?=\S*[ah])(?!.*[dieuoftrm])al[^a]..")

#This one is what I currently have but it feels messy to use multiple lookaheads
>>> re.compile("(?=\S*[a])(?=\S*[h])(?!.*[dieuoftrm])al[^a]..")
0 Answers
Related