Python原始字符串与Unicode:如何将网页输入用作正则表达式模式?

4 投票
3 回答
6089 浏览
提问于 2025-04-15 18:07

编辑:一旦你明白了“r”标志的意思,这个问题就不太有意义了。更多细节可以在这里找到。对于想要快速答案的人,我在下面添加了内容。

如果我在Python脚本中手动输入一个正则表达式,我可以用四种组合的标志来表示我的模式字符串:

  • p1 = "pattern"
  • p2 = u"pattern"
  • p3 = r"pattern"
  • p4 = ru"pattern"

我有一堆来自网页表单输入的Unicode字符串,想把它们用作正则表达式模式。

我想知道我应该对这些字符串做什么处理,这样我就能得到和上面手动输入的形式类似的结果。就像:

import re
assert re.match(p1, some_text) == re.match(someProcess1(web_input), some_text)
assert re.match(p2, some_text) == re.match(someProcess2(web_input), some_text)
assert re.match(p3, some_text) == re.match(someProcess3(web_input), some_text)
assert re.match(p4, some_text) == re.match(someProcess4(web_input), some_text)

那么,someProcess1到someProcessN应该是什么,为什么?

我猜想someProcess2不需要做任何事情,而someProcess1应该进行一些Unicode转换,以适应本地编码。至于原始字符串字面量,我就不知道该怎么处理了。

3 个回答

2

在你第一个例子中注意以下几点:

>>> p1 = "pattern"
>>> p2 = u"pattern"
>>> p3 = r"pattern"
>>> p4 = ur"pattern" # it's ur"", not ru"" btw
>>> p1 == p2 == p3 == p4
True

虽然这些写法看起来不一样,但它们做的事情是一样的,都是创建一个字符串对象(p1和p3是 str 类型,p2和p4是 unicode 类型,在Python 2.x中),里面的内容都是“pattern”。前面的 urur 只是告诉解析器怎么理解后面的字符串,也就是把它当作unicode文本(u)和/或原始文本(r),在原始文本中,反斜杠用来表示其他字符时会被忽略。不过最终无论字符串是怎么创建的,不管是原始字符串还是普通字符串,内部存储的方式都是一样的。

当你接收到unicode文本作为输入时,在Python 2.x中你需要区分它是 unicode 文本还是 str 对象。如果你想处理unicode内容,最好只使用unicode类型,并把所有的 str 对象转换成 unicode 对象(可以用 str.decode() 或者用 u'text' 这种写法来处理硬编码的文本)。如果你把它编码成本地编码,就会遇到unicode符号的问题。

另一种方法是使用Python 3,在这个版本中,str 对象直接支持unicode,所有内容都以unicode形式存储,你根本不需要担心编码的问题。

2

“r”标志的作用是让Python在处理字符串时不去解释反斜杠“\”。因为网络对数据的格式没有特别要求,所以你在网页上输入的数据其实就是一堆字节,你可以根据自己的需要来理解这些字节。

所以,要解决这个问题:

  • 确保你在整个过程中都使用Unicode(比如utf-8)
  • 当你获取到字符串时,它会是Unicode格式的,这样像“\n”、“\t”和“\a”这些字符就会被当作字面意思来看,你不需要担心是否要对它们进行转义。
7

除了可能需要在Python 2.*中正确处理Unicode编码之外,其实不需要做什么特别的处理,因为“原始字符串”并没有一个特定的类型——它只是一种语法,用来表示字面量,也就是字符串常量。而在你的代码片段中,并没有任何字符串常量,所以其实没有什么需要“处理”的东西。

撰写回答