简体   繁体   中英

python regex match A but not B in any order

This question has an answer here but I can't seem to be able to adopt it to my use case.

I want to match to a string that contains the word "reset" but not password. For example suppose I have the following two:

queries = ["reset my password", "reset my account please.", "password reset"]
for q in queries:
    print(is_reset(q))

should output False, True, False where is_reset would contain the regex.

The regex that I tried was:

matches = re.search("(?=reset)(?!.*password)", text)
if matches:
    print("Matched")
else:
    print("No match")

The above seems to have an issue with the last query. Also I am blindly copying the regex, couls someone explain what the regex above/ answer means?

The main problem with your current pattern (?=reset)(?..*password) is that while it does correctly have lookaheads which assert that reset is present and password is not present, the pattern itself is zero width, and so will never match any content which is not zero width. I would use this pattern:

^(?!.*\bpassword\b).*\breset\b.*$

This matches any input with reset appearing anywhere, and it has a negative assertion at the beginning to exclude password from being present.

Sample script:

queries = ["reset my password", "reset my account please.", "password reset"]
for q in queries:
    matches = re.search(r'^(?!.*\bpassword\b).*\breset\b.*$', q)
    if matches:
        print("Matched:  " + q)
    else:
       print("No match: " + q)

This prints:

No match: reset my password
Matched:  reset my account please.
No match: password reset

If you want to do this with regex, you have to a negative lookup on passsword and positive lookup on reset -

^(?=.*reset)(?..*password).*

This should work.

(?=.*reset) -> Matches when there is reset . (?..*password).* -> Dont match when there is password

The main problem was you were always expecting reset to be not have anything before it. add a .* before reset to indicate it can have characters before it as well. Similarly password can have charcters after it as well. hence the .* after password

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM