We should cover all the cases of beta version names, where the regexp should give a match.
So we start writing the pattern with the first example of beta "Crome beta":
' [Bb]eta'
We use [Bb] to match B or b in the second place.
The second example "Crome_beta" adds _ as a separator:
'[ _][Bb]eta'
The third "Crome beta2" and the forth "Crome_betaversion" examples are covered by the last regexp.
The fifth example "Crome 3beta" forces us to change the pattern this way:
'[ _]\d*[Bb]eta'
where \d is a substitute for [0-9] and * allows from 0 to infinity elements of \d.
The sixth example "CromeBeta2.3" shows that Beta can have no preceding _ or space, just start with the capital. So we cover it with | construction which is the same as or operator in Python:
'[ _]\d*[Bb]eta|Beta'
The seventh example Beta Crome 4 is matched by the least regexp (since it starts with Beta). But it can also be beta Chrome 4, so we would change the pattern this way:
'[ _]\d*[Bb]eta|Beta|^beta '
We don't use ^[Bb]eta since Beta is already covered.
Also, I should mention, we can't use re.I since we have to differentiate between beta and Beta in the regex.
So, the test code is (for Python 2.7):
from __future__ import print_function
import re, sys
match_tests = [
"Crome beta",
"Chrome Beta",
"Crome_beta",
"Crome beta2",
"Crome_betaversion",
"Crome 3beta" ,
"Crome 3Beta",
"CromeBeta2.3",
"Beta Crome 4",
"beta Chrome ",
"Cromebeta2.3" #no match,
"betamax" #no match,
"Betamax"]
compiled = re.compile(r'[ _]\d*[Bb]eta|Beta|^beta ')
for test in match_tests:
search_result = compiled.search(test)
if search_result is not None:
print("{}: OK".format(test))
else:
print("{}: No match".format(test), file=sys.stderr)
I don't see any need to use negative lookbehind.
Also, you used a capturing group (beta) (parenthesis). There is no need for it either. It would just slow down the regexp.
"beta in product_name.lower()