Python正则表达式坏字符范围.

use*_*355 14 python regex

我正在使用以下正则表达式来匹配不同的日期模式.它在regex101.com中运行良好.但是当我导入到python时,我得到了"不良角色范围"异常.

  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
Run Code Online (Sandbox Code Playgroud)

Avi*_*Raj 28

问题主要是因为[\s-/']字符类中存在连字符,因此Python将其解释为字符间隔(如in [a-z]).我建议你把连字符放在字符类的第一个或最后一个位置,[-\s/']或者将其转义,以防止歧义.

>>> 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]))))))")
>>> 
Run Code Online (Sandbox Code Playgroud)

  • @Travis连字符用于正则表达式(特别是在正则表达式中的`[]`里面)表示字符范围,例如`[az]`表示任何小写字母字符.在这种情况下,`[\ s - /']`不是一个字符范围,所以Python抱怨它是一个"坏字符范围".将连字符放在开头或结尾(或转义它)使得Python不会将其解释为字符范围. (5认同)