【问题标题】:Does python re (regex) have an alternative to \u unicode escape sequences?python re (regex) 是否可以替代 \u unicode 转义序列?
【发布时间】:2013-05-08 15:33:15
【问题描述】:

Python 将 \uxxxx 视为字符串文字中的 unicode 字符转义(例如 u"\u2014" 被解释为 Unicode 字符 U+2014)。但我刚刚发现(Python 2.7)标准正则表达式模块不会将 \uxxxx 视为 unicode 字符。示例:

codepoint = 2014 # Say I got this dynamically from somewhere

test = u"This string ends with \u2014"
pattern = r"\u%s$" % codepoint
assert(pattern[-5:] == "2014$") # Ends with an escape sequence for U+2014
assert(re.search(pattern, test) != None) # Failure -- No match (bad)
assert(re.search(pattern, "u2014")!= None) # Success -- This matches (bad)

显然,如果您能够将您的正则表达式模式指定为字符串文字,那么您可以获得与正则表达式引擎本身理解 \uxxxx 转义一样的效果:

test = u"This string ends with \u2014"
pattern = u"\u2014$"
assert(pattern[:-1] == u"\u2014") # Ends with actual unicode char U+2014
assert(re.search(pattern, test) != None)

但是如果您需要动态构建模式怎么办?

【问题讨论】:

  • 您首先创建一个字符串'\u%s,然后插入代码点,这首先解释为\u....。那是预期的行为。请改用u'%s' % unichr(codepoint)

标签: python regex unicode python-unicode unicode-escapes


【解决方案1】:

使用 unichr() function 从代码点创建 unicode 字符:

pattern = u"%s$" % unichr(codepoint)

【讨论】:

  • 这是我示例的一个很好的解决方案。但这也让我意识到我的例子并没有体现出我真正希望问的问题。我不太关心将单个代码点注入到已知形式的字符串中,而更关心如何处理任意字符串中未指定数量的 \u 转义。这就是我试图用自己的答案进入的方向——尽管也许我应该使用 unichr 作为其中的一部分。
  • @Chris:我介绍了在 this previous answer 中使用正则表达式替换 just \uxxxx 转义。
  • "%s$" 是什么意思?
  • @alvas:%s是字符串插值的占位符;它被表达式unichr(codepoint) 的输出替换。 $ 是一个正则表达式元字符,意思是“匹配行尾”。
【解决方案2】:

一种可能性是,而不是直接调用 re 方法,将它们包装在可以理解 \u 代表它们转义的东西中。像这样的:

def my_re_search(pattern, s):
    return re.search(unicode_unescape(pattern), s)

def unicode_unescape(s):
        """
        Turn \uxxxx escapes into actual unicode characters
        """
        def unescape_one_match(matchObj):
                escape_seq = matchObj.group(0)
                return escape_seq.decode('unicode_escape')
        return re.sub(r"\\u[0-9a-fA-F]{4}", unescape_one_match, s)

工作示例:

pat  = r"C:\\.*\u20ac" # U+20ac is the euro sign
>>> print pat
C:\\.*\u20ac

path = ur"C:\reports\twenty\u20acplan.txt"
>>> print path
C:\reports\twenty€plan.txt

# Underlying re.search method fails to find a match
>>> re.search(pat, path) != None
False

# Vs this:
>>> my_re_search(pat, path) != None
True

感谢Process escape sequences in a string in Python 指出 decode("unicode_escape") 的想法。

但请注意,您不能只通过 decode("unicode_escape") 抛出整个模式。它有时会起作用(因为当您在前面放置反斜杠时,大多数正则表达式特殊字符不会改变它们的含义),但通常不会起作用。例如,这里使用 decode("unicode_escape") 会改变正则表达式的含义:

pat = r"C:\\.*\u20ac" # U+20ac is the euro sign
>>> print pat
C:\\.*\u20ac # Asks for a literal backslash

pat_revised  = pat.decode("unicode_escape")
>>> print pat_revised
C:\.*€ # Asks for a literal period (without a backslash)

【讨论】:

    猜你喜欢
    • 2015-12-07
    • 2022-01-02
    • 1970-01-01
    • 2011-05-29
    • 2021-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多