【问题标题】:Python regex bad character range.Python 正则表达式错误的字符范围。
【发布时间】:2015-04-16 20:03:18
【问题描述】:

我正在使用以下正则表达式来匹配不同的日期模式。它在 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

【问题讨论】:

  • 你运行的是哪个版本的python?
  • @AvinashRaj - 我包含了很多连字符。我怀疑,这不会是因为常规连字符( - )对吗?但是,regex101.com 怎么没有报错。
  • @AvinashRaj - 我正在使用 python 2.7
  • 有很多库可以为你做到这一点。这里不需要正则表达式。
  • 问题出在:[\s-/'],换成[\s/'-]

标签: python regex


【解决方案1】:

问题主要是因为[\s-/']字符类中存在连字符,因此Python将其解释为字符间隔(如[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]))))))")
>>> 

【讨论】:

  • 我知道了。但有一个疑问。这里的其他一些表达式有相同类型的连字符,甚至不是在末尾。但似乎只有这一个是错误的。
  • 我认为这是因为 , of \s (匹配任何垂直或水平空格字符)。所以 re 模块未能找到多个字符和正斜杠之间的范围。 re 模块就是这样设计的。
  • 谢谢哥们。感谢您抽出时间分享知识和信息。
  • 那么这里的连字符是干什么的。即为什么它需要在字符串的开头或结尾?
  • @Travis 在正则表达式中使用连字符(特别是在正则表达式中的 [] 内部)来表示字符范围,例如[a-z] 表示任何小写字母字符。在这种情况下,[\s-/'] 不是字符范围,因此 Python 抱怨它是“错误的字符范围”。将连字符放在开头或结尾(或转义)会使 Python 不会将其解释为字符范围。
猜你喜欢
  • 1970-01-01
  • 2015-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-20
  • 1970-01-01
  • 2019-06-22
  • 2019-05-29
相关资源
最近更新 更多