1

I'm trying to create a small, text restriction program in python. Basically, the user inputs the text, some filters (a for alphabetic, n for numeric, etc.). The user can combine filters (a and n for alpha-numeric, etc.) but I stumbled upon this:

if re.match("[a-zA-Z]", textToRestrict):
    return True
else:
    return False

Here's where things fall apart. Supposedly, with only alphabetic as a filter, the program will only accept strings, such as, say, dance. However, the if statement still returns true if the textToRestric was, say, dance1234 (incorrect) while 1234dance will return false (correct).

Conversely, if I test for digits via [0-9], it would still return true even if it contains alphabetic characters, provided that the characters aren't the first.

How do I use regex to match only a certain type, and in such a way that adding another type to it (like type string + type digit) allows for both types return true?

UPDATE: This is the approach I used for multiple filters:

regex = ""
if FilterClass.ALPHABETIC in arguments:
    regex += "[a-zA-Z]"
if FilterClass.CAPITAL_ALPHABETIC in arguments:
    regex += "[A-Z]"
if FilterClass.NUMERIC in arguments:
    regex += "\d"
if FilterClass.SPECIAL_CHARACTERS in arguments:
    regex += "[^0-9a-zA-Z]*"
if FilterClass.DASH_UNDERSCORES in arguments:
    regex += "[-_]*"            

regall = "^(" + regex + ")+$"

if re.match(regall, textToRestrict):
    return True
else:
    return False

arguments is a parameter inputted in by the user. The if statements check what's in there, and, supposedly, add more patterns to the regex string.

3
  • 1
    why not use str.isalpha() and str.isdigit()? Commented Dec 1, 2015 at 20:22
  • your regex doesn't positionally check where in the string it is at, and doesn't match against anything more than the first character ^[a-zA-Z]+$ matches from the start to the end, on one or more matching occurrences of alphabetics until the end of the string. Commented Dec 1, 2015 at 20:22
  • @SirParselot, because ideally, the user can input alpha, digit, special characters, or any combination of those, for as long as they use the proper filter. I'm not sure isalpha() and isdigit() could be used for that. Commented Dec 1, 2015 at 20:26

1 Answer 1

5

Add anchors at both ends of the regex, plus a quantifier (+ if you want to exclude the empty string; * if you want to permit the empty string). Right now, you're just checking to see whether the first character (singular) is alphabetic (i.e. matches [a-zA-Z]).

What you want is:

re.match("^[a-zA-Z]+$", textToRestrict)

(Or, if your filters are really this simple, consider using string methods like str.isalpha instead, as SirParselot suggests in a comment.)

Sign up to request clarification or add additional context in comments.

11 Comments

the left anchor isn't needed if you're testing with match() though.
@Felk Strictly speaking, you're right - it isn't. I'd prefer to have it in there anyway for explicitness's sake.
That worked for one, thanks. If treated as a string, can I just add on to that pattern, or do I need to have the +$ at the very end? I've updated my post above to show how I currently do things for clarity.
@zack_falcon The + means "match the thing immediately before me 1 or more times". The $ means "match the end of the string". If you want to match alphanumerics, you'd need something like ^[0-9a-zA-Z]+$ if you want to use regexes. If you want to build these regexes piece by piece, you'd want to use an alternation like [0-9]|[a-zA-Z] and then wrap it in ^(...)+$.
Isn't the pipe an or? Would that mean it would check if there's a [0-9] or a [a-zA-Z] until the end?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.