【问题标题】:Django - storing a raw string literal in model for regex use?Django - 在模型中存储原始字符串文字以供正则表达式使用?
【发布时间】:2011-10-13 23:00:50
【问题描述】:

我有 Django 模型,我需要在其中一个字段中存储一个正则表达式字符串,以便稍后使用:

class Foo(models.Model):
    name = models.CharField(max_length=30, unique=True)
    regex_string = models.TextField()

例如,regex_string 字段可能设置为:

r'\d{2}'

然后我稍后尝试检索它,将其编译为正则表达式并使用它 - 但是,它似乎没有按计划工作:

>>> pattern = re.compile(ham.regex_string)
>>> print(pattern.match("22"))
None

显然,如果我直接传递原始字符串文字,它可以正常工作:

>>> pattern = re.compile(r'\d{2}')
>>> pattern.match("22")
<_sre.SRE_Match object at 0x1505100>

如果我真的打印 ham.regex_string,它会返回:

u"r'\\d{2}'"

所以它是一个 unicode 字符串,但由于某种原因,反斜杠加倍了?有没有更好的方法在 Django 模型中存储正则表达式模式,以便我以后可以使用它?

干杯, 维克多

编辑:感谢大家的回答 =)。我已将答案授予 rczajka,因为他是帖子的第一部分(至少如果要相信 StackOverflow 时间戳的话)。

只是为了澄清问题,该字段是由用户在表单 (django-admin) 上输入的。以前,他们在 with r'' 中输入正则表达式 - 例如r'\d{2}\。但是,如果我只是让他们输入字符串文字本身 \d{2},它现在似乎可以工作 - Django 不会篡改字符串或解释反斜杠 - 没有理由应该这样做,对吧?

【问题讨论】:

    标签: regex django django-models


    【解决方案1】:

    你只需要在找回它之后变得更聪明。

    >>> import ast
    >>> print ast.literal_eval(u"r'\\d{2}'")
    \d{2}
    

    【讨论】:

      【解决方案2】:

      呃,不要存储文字(即"r'\d{2}'"),存储它产生的内容。

      foo    = Foo.objects.create(regex_string = r'\d{2}')
      foo_re = re.compile(foo.regex_string)
      

      【讨论】:

        【解决方案3】:

        如何设置 regex_string 字段?您是否可能在页面上输入内容? r'' 符号只是语法糖:

        >>> r'\d{2}'
        '\\d{2}'
        >>> print r'\d{2}'
        \d{2}
        

        因此,如果您想在输入中输入内容,请编写实际的正则表达式字符串 (\d{2}),而不是 Python 文字。

        【讨论】:

          【解决方案4】:

          这是一个非常奇怪的错误。 Python 原始字符串只是一种语法便利(它评估为常规字节字符串),所以我看不出它是如何获得u"r'\\d{2}" 的。我能想到的只是你以某种方式在文字周围写了双引号,这不太可能是错误。

          当我跑步时

          from someproject.someapp.models import *
          ham = Foo(name=u'test', regex_string=r'\d{2}')
          ham.save()
          ham = Foo.objects.get(name=u'test')
          print ham.regex_string
          

          manage.py shell 中,我得到了Unicode 字符串\d{2}(如预期的那样)。

          您说您打印了ham.regex_string,但看起来您实际上只是在 Python 交互式控制台中对其进行了评估。这给出了一个对象的repr,在本例中为u'\\d{2}'。加倍的\\ 仅用于展示;该字符串实际上包含一个\

          另外:您实际上是在使用正则表达式来匹配二进制字符串吗?如果没有,您应该改用 Unicode 正则表达式 ur'\d{2}'。如果是,则应显式对正则表达式进行 Base64 编码,因为通常二进制正则表达式不是有效的 UTF-8,因此不会正确存储在数据库中。

          【讨论】:

          • 如果有人在TextField 中键入“r'\d{2}'”,这是可能的。
          猜你喜欢
          • 2017-10-17
          • 2015-07-21
          • 1970-01-01
          • 1970-01-01
          • 2017-05-30
          • 2015-12-18
          • 1970-01-01
          • 1970-01-01
          • 2015-11-28
          相关资源
          最近更新 更多