【问题标题】:String comparison in Python 3Python 3 中的字符串比较
【发布时间】:2019-09-19 07:12:04
【问题描述】:

我的字符串比较不起作用,

有什么想法吗?

a = person.category[0].lower()
b = to_delete[5].lower()

print("test ", repr(a), "type: ", type(a))
print("test ", repr(b), "type: ", type(b))
print(a == b)
print(a is b)
print("éclairage public" == b)
print("éclairage public" == a )

返回:

test  'éclairage public' type:  <class 'str'>
test  'éclairage public' type:  <class 'str'>
False
False
False
True

所以“b”没有预期的成分,但我不知道为什么!

【问题讨论】:

  • 简单的print(a)print(b) 的输出是什么?
  • 显然我希望一切都是真的!
  • 如果您不提供person.categoryto_delete的内容,我们将无法重现该问题。
  • 您可能遇到了 Unicode 规范化问题。比较a.encode()b.encode()的值
  • 比较b'e\xcc\x81'.decode()b'\xc3\xa9'.decode()的结果。两者看起来都像é,但它们是两个不同的Unicode字符串。

标签: python python-3.x string compare string-comparison


【解决方案1】:

您的问题几乎可以肯定是ab 是具有相同规范化 的两个不同的Unicode 值。举个简单的例子,考虑这两种显示é的方式:

>>> b'e\xcc\x81'.decode()
'é'
>>> b'\xc3\xa9'.decode()
'é'

第一个是由e (U+0065) 和组合变音符号´ (U+0301) 组成的两个字符的字符串。第二个是由é (U+00E9) 组成的单个字符。

为了成功比较它们,您需要对它们进行规范化。有几种不同的标准化可供使用,但您使用哪一种对于比较而言并不重要,只要您为每种标准化使用相同的

>>> import unicodedata
>>> x = b'e\xcc\x81'.decode()
>>> y = b'\xc3\xa9'.decode()
>>> x == y
False
>>> unicodedata.normalize("NFC", x) == unicodedata.normalize("NFC", y)
True

标准化 NFC,例如,通过将 U+0065/U+0301 替换为 U+00E9 进行标准化。有关详细信息,请参阅https://www.unicode.org/faq/normalization.html。您可能希望在存储任何用户输入之前对其进行规范化,并且您需要确保对所有存储的数据使用相同的规范化。常见问题解答可以帮助您确定最适合您使用的规范化。

【讨论】:

  • 一种更简洁的方法应该是编码/解码字符串,但我不知道该怎么做。一个条目来自网络(selenium),第二个来自手动创建字符串。
  • 编码/解码是一个单独的问题。您需要先解码一个 UTF-8 字节字符串,然后才能对结果进行规范化,并且您(可能)需要将规范化的结果编码回 UTF-8 进行存储。
猜你喜欢
  • 2012-06-14
  • 2013-11-26
  • 2018-03-27
  • 2019-01-17
  • 1970-01-01
  • 2016-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多