Re: [Tutor] Regex not working as desired
On Mon, 26 Feb 2018, Roger Lea Scherer wrote: """ ensure input is no other characters than digits sudocode: if the input has anything other than digits return digits """ p = re.compile(r'[^\D]') I'm not so great at regular expressions, but this regex appears to be searching for a string that matches anything in the class start-of-string of non-digit. "[...]" says, look for anything in this set of characters; and you have two things: ^ : start-of-string \D : any non-digit Instead of looking fo re xcaprions, I would look for what you *do* want. this regex should do it for you: r'^\d+$' This is looking for a start-of-string ("^"); then a digit ("\d") that occurs at least once (the "+" qualifier); then an end-of string ("$"). In other words, one or more digits, with nothing else before or after. Here's a simple looping test to get you started (ignore the "from __future__" line; I'm running Python 2): from __future__ import print_function import re p = re.compile(r'^\d+$') test_data = ["4jkk33", "4k33", "4jjk4", "4334", "4","44", "444", ""] for thing in test_data: m = p.match(thing) if m is None: print("not all digits:", thing) else: print("all digits:", thing) -- Terry Carroll carr...@tjc.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Regex not working as desired
On Mon, 26 Feb 2018, Terry Carroll wrote: Instead of looking fo re xcaprions.. Wow. That should read "Instead of looking for exceptions..." Something really got away from me there. -- Terry Carroll carr...@tjc.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Regex not working as desired
On Mon, Feb 26, 2018 at 11:01:49AM -0800, Roger Lea Scherer wrote: > The first step is to input data and then I want to check to make sure > there are only digits and no other type of characters. I thought regex > would be great for this. I'm going to quote Jamie Zawinski: Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. Welcome to the club of people who discovered that regexes are just as likely to make things worse as better :-( Here's another, simpler way to check for all digits: value = '12345' # for example value.isdigit() The isdigit() method will return True if value contains nothing but digits (or the empty string), and False otherwise. Sounds like just what you want, right? Nope. It *seems* good right up to the moment you enter a negative number: py> '-123'.isdigit() False Or you want a number including a decimal point. Floating point numbers are *especially* tricky to test for, as you have to include: # mantissa optional + or - sign zero or more digits optional decimal point (but no more than one!) zero or more digits but at least one digit either before or after the decimal point; # optional exponent E or e optional + or - sign one or more digits It is hard to write a regex to match floats. Which brings us to a better tactic for ensuring that values are a valid int or float: try it and see! Instead of using the Look Before You Leap tactic: if string looks like an int: number = int(string) # hope this works, if not, we're in trouble! else: handle the invalid input we can use the "Easier To Ask For Forgiveness Than Permission" tactic, and just *try* converting it, and deal with it if it fails: try: number = int(string) except ValueError: handle the invalid input The same applies for floats, of course. Now, one great benefit of this is that the interpreter already knows what makes a proper int (or float), and *you don't have to care*. Let the interpreter deal with it, and only if it fails do you have to deal with the invalid string. By the way: absolute *none* of the turtle graphics code is the least bit relevant to your question, and we don't need to see it all. That's a bit like going to the supermarket to return a can of beans that you bought because they had gone off: "Hi, I bought this can of beans yesterday, but when I got it home and opened it, they were all mouldy and green inside. Here's my receipt, and the can, and here's the can opener I used to open them, and the bowl I was going to put the beans into, and the microwave oven I would have used to heat them up, and the spoon for stirring them, and the toast I had made to put the beans on, and the salt and pepper shakers I use." :-) -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Regex not working as desired
On 27/02/18 05:13, Cameron Simpson wrote: > hard to debug when you do. That's not to say you shouldn't use them, but many > people use them for far too much. > Finally, you could also consider not using a regexp for this particular task. > > Python's "int" class can be called with a string, and will raise an exception And, as another alternative, you can use all() with a generator expression: >>> all(c.isdigit() for c in '1234') True >>> all(c.isdigit() for c in '12c4') False >>> Or generally: def all_digits(s): return all(c.isdigit() for c in s) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Regex not working as desired
Alan Gauld via Tutor wrote: > On 27/02/18 05:13, Cameron Simpson wrote: > >> hard to debug when you do. That's not to say you shouldn't use them, but >> many people use them for far too much. > > >> Finally, you could also consider not using a regexp for this particular >> task. Python's "int" class can be called with a string, and will raise an >> exception > > And, as another alternative, you can use all() with a > generator expression: > all(c.isdigit() for c in '1234') > True all(c.isdigit() for c in '12c4') > False > > Or generally: > > def all_digits(s): > return all(c.isdigit() for c in s) Note that isdigit() already checks all characters in the string: >>> "123".isdigit() True >>> "1a1".isdigit() False The only difference to your suggestion is how it handles the empty string: >>> def all_digits(s): ... return all(c.isdigit() for c in s) ... >>> all_digits("") True >>> "".isdigit() False A potential problem of str.isdigit() -- and int() -- may be its unicode awareness: >>> s = "\N{CHAM DIGIT ONE}\N{CHAM DIGIT TWO}\N{CHAM DIGIT THREE}" >>> s '꩑꩒꩓' >>> s.isdigit() True >>> int(s) 123 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Regex not working as desired
On 27/02/18 09:50, Peter Otten wrote: >> def all_digits(s): >> return all(c.isdigit() for c in s) > > Note that isdigit() already checks all characters in the string: Ah! I should have known that but forgot. I think the singular name confused me. > The only difference to your suggestion is how it handles the empty string: > def all_digits(s): > ... return all(c.isdigit() for c in s) > ... all_digits("") > True "".isdigit() > False Interesting, I'd have expected all() to return False for an empty sequence... But looking at help(all) it clearly states that it returns True. RTFM! :-( However, in practice, and for this specific case, the try/except route is probably best, I just wanted to point out that there were other (concise) ways to avoid a regex. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor