30

I am using the following regex to match different patterns of dates. it works fine in regex101.com. But when I import to python i am getting "bad character range" exception.

  pattern = ur"((?:\b((?:(january|jan|february|feb|march|mar|april|apr|may|jun|june|july|jul|august|aug|september|set|sep|october|oct|november|nov|december|dec)['\s\.]{0,4}(?:\d{4}|\d{2})|(?:january|jan|february|feb|march|mar|april|apr|may|jun|june|july|jul|august|aug|september|set|sep|october|oct|november|nov|december|dec)|((?:0[1-9]|[1-3][0-9]|[0-9])/(?:0[1-9]|[1-3][0-9])/(?:(19[7-9][0-9])|(20[0-1][0-9])|([7-9][0-9]|[0-1][0-9]))|((?:0[1-9]|1[0-2]|[1-9])\s{0,3}[-/']{1,3}[\s-/']{0,3}(?:(19[7-9][0-9])|(20[0-1][0-9])|([7-9][0-9]|[0-1][0-9])))))(?:(?![\r\n])\s){0,4})[-/–to]{0,2}(?:(?![\r\n])\s){0,4}(((?:january|jan|february|feb|march|mar|april|apr|may|jun|june|july|jul|august|aug|september|set|sep|october|oct|november|nov|december|dec)[-'\s\.]{0,4}(?:(19[7-9][0-9])|(20[0-1][0-9])|([7-9][0-9]|[0-1][0-9])))|((?:0[1-9]|[1-3][0-9]|[1-9])/(?:0[1-9]|[1-3][0-9])/(?:(19[7-9][0-9])|(20[0-1][0-9])|([7-9][0-9]|[0-1][0-9])))|((?:0[1-9]|1[0-2]|[1-9])\s{0,3}[-/']{1,3}[\s-/']{0,3}(?:(19[7-9][0-9])|(20[0-1][0-9])|([7-9][0-9]|[0-1][0-9]))))))"

  https://regex101.com/r/rU3cE9/1
8
  • Which version of python are you running? Commented Feb 16, 2015 at 10:26
  • @AvinashRaj - I include a lot of hyphens. I have a doubt that, it won't be because of regular hyphen ( - ) right ? But, how come regex101.com doesn't show a error. Commented Feb 16, 2015 at 10:27
  • @AvinashRaj - I am using python 2.7 Commented Feb 16, 2015 at 10:27
  • There are many libraries that does that for you.. no need for regex here. Commented Feb 16, 2015 at 10:28
  • 3
    The problem is here: [\s-/'], replace it with [\s/'-]. Commented Feb 16, 2015 at 10:33

1 Answer 1

58

Problem is mainly because of the hyphen present inside [\s-/'] character class, therefore Python interprets it as a character interval (like in [a-z]). I suggest you to put the hyphen at the first or at the last position inside the character class [-\s/'] or escape it, to prevent ambiguity.

>>> reg = re.compile(ur"((?:\b((?:(january|jan|february|feb|march|mar|april|apr|may|jun|june|july|jul|august|aug|september|set|sep|october|oct|november|nov|december|dec)['\s\.]{0,4}(?:\d{4}|\d{2})|(?:january|jan|february|feb|march|mar|april|apr|may|jun|june|july|jul|august|aug|september|set|sep|october|oct|november|nov|december|dec)|((?:0[1-9]|[1-3][0-9]|[0-9])/(?:0[1-9]|[1-3][0-9])/(?:(19[7-9][0-9])|(20[0-1][0-9])|([7-9][0-9]|[0-1][0-9]))|((?:0[1-9]|1[0-2]|[1-9])\s{0,3}[-/']{1,3}[-\s/']{0,3}(?:(19[7-9][0-9])|(20[0-1][0-9])|([7-9][0-9]|[0-1][0-9])))))(?:(?![\r\n])\s){0,4})[-/to–]{0,2}(?:(?![\r\n])\s){0,4}(((?:january|jan|february|feb|march|mar|april|apr|may|jun|june|july|jul|august|aug|september|set|sep|october|oct|november|nov|december|dec)[-'\s\.]{0,4}(?:(19[7-9][0-9])|(20[0-1][0-9])|([7-9][0-9]|[0-1][0-9])))|((?:0[1-9]|[1-3][0-9]|[1-9])/(?:0[1-9]|[1-3][0-9])/(?:(19[7-9][0-9])|(20[0-1][0-9])|([7-9][0-9]|[0-1][0-9])))|((?:0[1-9]|1[0-2]|[1-9])\s{0,3}[-/']{1,3}[-\s/']{0,3}(?:(19[7-9][0-9])|(20[0-1][0-9])|([7-9][0-9]|[0-1][0-9]))))))")
>>> 
Sign up to request clarification or add additional context in comments.

5 Comments

I got this. But one doubt. Some other expressions here had same type of hyphen, and that was even not at the end. But only this one seem to be caused an error.
i think it's because , of \s (matches any vertical or horizontal space character). So re module failed to find a range between multiple chars and a forward slash. re module is designed like that.
Thanks man. Thanks that you find time to share knowledge and info.
So what is the hyphen doing here. i.e. Why does it need to be at the beginning or end of the string?
@Travis A hyphen is used in regexes (specifically inside [] in regexes) to denotes a character range, e.g. [a-z] denotes any lowercase alphabetic character. In this case, [\s-/'] is not a character range, so Python complains that it is a "bad character range". Putting the hyphen at the beginning or end (or escaping it) makes Python not interpret it as a character range.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.