2

Trying to create a function which with a given a regular expression which holds all the legal characters, a string will be checked if it only contains those characters.

For example

import re
legal_characters = r'[\*\-]' # Matches asterisc and dash characters

def is_legal(test_string):
    if re.match(legal_characters, test_string):
        print("Legal")
    else:
        print("Not legal")

is_legal("***---123")  # should print "Not legal"
is_legal("AbC123")     # should print "Not legal"
is_legal("*-*-*")      # should print "Legal"

output:

Not legal
Not legal
Not legal

I do not really understand why. Could someone please explain?

  • tested on python 3.4: all strings are legal; `re` matches the first letter only (`<_sre.SRE_Match object; span=(0, 1), match='a'>`). – hiro protagonist Dec 18 '16 at 08:13
  • @hiroprotagonist I made a poor choice of a regular expression. Please see modified description.. –  Dec 18 '16 at 08:16
  • TigerhawkT3 is right, this is a duplicate no matter how small the differences are. Please look at http://stackoverflow.com/questions/1323364/in-python-how-to-check-if-a-string-only-contains-certain-characters which holds a more complete answer as well. –  Dec 18 '16 at 09:33

4 Answers4

2

Try this:

import re
legal_characters = r'\w+$' # Matches Unicode word characters
r = re.compile(legal_characters)

def is_legal(test_string):
    if re.match(r, test_string):
        print("Legal")
    else:
        print("Not legal")

is_legal("aaaAA$")  # should print "Not legal"
is_legal("AAAA***") # should print "Not legal"
is_legal("AAABBB")  # should print "Legal"

Tested on python 2.7.12.

Nurjan
  • 5,889
  • 5
  • 34
  • 54
2

this reproduces what you want: ^ matches the beginning of the string $ the end. in between there are repeating + characters \w = [A-Za-z0-9_].

legal_characters = '^\w+$'

update

after the modification of your question this is my suggestion:

^ matches the beginning of the string $ the end. in between there are repeating + elements of [*-]:

legal_characters = '^[*-]+$'

there is no need to escape *- with \.

as pointed out by Maroun Maroun you can leave out the ^ as match scans the beginning of the string anyway:

legal_characters = '[*-]+$'
hiro protagonist
  • 44,693
  • 14
  • 86
  • 111
1

You don't need to use re. Try:

legal_characters = '*-'

def is_legal(test_string):
    for s in test_string:
        if s not in legal_characters:
            print("Not legal")
            return
    print("Legal")

And the output is:

>>> is_legal("***---123")
Not legal
>>> is_legal("AbC123") 
Not legal
>>> is_legal("*-*-*")
Legal
ebeneditos
  • 2,542
  • 1
  • 15
  • 35
  • Note that this would include the brackets as allowed characters, which they're not supposed to be. I'd recommend defining `legal_characters = {'*', '-'}`. You could also simplify this to `def is_legal(test_string): return all(c in legal_characters for c in test_string)`. – TigerhawkT3 Dec 18 '16 at 08:34
  • Okay thought bracets were legal as well. Yes I like the simplification but I think he wants a function which prints, not returns, if I understood correctly. – ebeneditos Dec 18 '16 at 08:39
  • That's probably just to simplify the test calls. – TigerhawkT3 Dec 18 '16 at 08:40
  • Okay thank you, I edited it with the simplification propose as well. – ebeneditos Dec 18 '16 at 08:44
  • Thank you for your answer. However, as I say in my question, I do want to use regular expressions. Among other reasons, with regular expression it will be much faster. –  Dec 18 '16 at 08:56
1
import re
legal_characters = r'[*-]+' # Matches asterisc and dash characters

def is_legal(test_string):
    if re.fullmatch(legal_characters, test_string):
        print("Legal")
    else:
        print("Not legal")
is_legal("***---123")  # should print "Not legal"
is_legal("AbC123")     # should print "Not legal"
is_legal("*-*-*")      # should print "Legal"

out:

Not legal
Not legal
Legal

first:

Special characters lose their special meaning inside sets. For example, [(+*)] will match any of the literal characters ’(’, ’+’, ’*’, or ’)’

than:

re.fullmatch(pattern, string, flags=0)

If the whole string matches the regular expression pattern, return a corresponding match object. Return None if the string does not match the pattern; note that this is different from a zero-length match.

宏杰李
  • 11,820
  • 2
  • 28
  • 35