当前位置: 首页 > 知识库问答 >
问题:

Python:比较字符串与重音字符不工作

卢树
2023-03-14

我对蟒蛇很陌生。我试图从另一个列表中删除出现在一个列表中的文件。这些列表是通过在mac和windows上重定向ll-R生成的(但是自从使用其他python脚本进行合并、排序等处理之后)。有些文件名有重音和特殊符号。这些字符串,即使它们是相同的(打印相同,在包含列表的文件中看起来相同),也被发现是不相等的。

我找到了关于如何在Unicode中比较字符串与特殊字符的线程:Python字符串比较-特殊/Unicode字符的问题这与我的问题非常相似。我做了更多关于编码和如何改变字符串编码的阅读。然而,我尝试了所有的编解码器我能找到的编解码器留档:https://docs.python.org/2/library/codecs.html对于所有可能的编解码器对两个字符串不相等(见下面的程序-尝试了解码和编码选项)。

当我逐个检查两个字符串中的字符时,重音e在一个文件中显示为重音e(一个字符),在另一个文件中显示为两个字符(e,可打印为空格)。

任何想法都将不胜感激。

我把这两个文本文件缩小到一行,每行一个单词(显然带有重音)。我将文本文件上传到dropbox:testfilesindata和testmissingfiles(但没有尝试从dropbox下载新的副本)。

非常感谢!

另外,很抱歉弄乱了链接。我没有名声10。。。

#!/usr/bin/python3

import sys

codecs = [ 'ascii', 'big5', 'big5hkscs', 'cp037', 'cp424', 'cp437', 'cp500', 'cp720      ', 'cp737   ', 'cp775', 'cp850', 'cp852', 'cp855', 'cp856   ', 'cp857', 'cp858', 'cp860', 'cp861', 'cp862', 'cp863', 'cp864', 'cp865', 'cp866', 'cp869', 'cp874     ', 'cp875   ', 'cp932', 'cp949', 'cp950', 'cp1006   ', 'cp1026', 'cp1140', 'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255', 'cp1256', 'cp1257', 'cp1258', 'euc_jp', 'euc_jis_2004', 'euc_jisx0213', 'euc_kr', 'gb2312', 'gbk', 'gb18030', 'hz', 'iso2022_jp', 'iso2022_jp_1', 'iso2022_jp_2', 'iso2022_jp_2004', 'iso2022_jp_3', 'iso2022_jp_ext', 'iso2022_kr', 'latin_1', 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', 'iso8859_7', 'iso8859_8', 'iso8859_9', 'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15', 'iso8859_16', 'johab', 'koi8_r   ', 'koi8_u      ', 'mac_cyrillic', 'mac_greek', 'mac_iceland', 'mac_latin2', 'mac_roman', 'mac_turkish', 'ptcp154', 'shift_jis', 'shift_jis_2004', 'shift_jisx0213', 'utf_32', 'utf_32_be', 'utf_32_le', 'utf_16', 'utf_16_be', 'utf_16_le', 'utf_7', 'utf_8', 'utf_8_sig' ]

file1 = open('testmissingfiles','r')
file2 = open('testfilesindata','r')

list1 = file1.readlines()
list2 = file2.readlines()

word1 = list1[0].rstrip('\n')
word2 = list2[0].rstrip('\n')

for i in range(0,len(codecs)-1):
    for j in range(0,len(codecs)-1):
        try:
            encoded1 = word1.decode(codecs[i])
            encoded2 = word2.decode(codecs[j])

            if encoded1 == encoded2:
                sys.stdout.write('Succeeded with ' + codecs[i] + ' & ' + codecs[j] + '\n')
        except:
            pass

共有2个答案

滑令
2023-03-14

您的程序有一些问题:

您的程序将生成AttributeError异常,从而在每个循环中通过。word1word2都没有名为的方法。解码()。在Python3中,可以将字符串编码为字节序列,也可以将字节序列解码为字符串。

使用编解码器是一种危险的做法。您的两个输入文件都是UTF-8编码的。从文件中读取字节时,文件中的字节将被成功解码。

字符串外观相似,但由不同的unicode代码点组成。具体而言,“附加”包括两个unicode代码点0065和0301、“拉丁小写字母E”和“组合锐重音”。另一方面,第二个单词“Adhésion”包含单个代码点00E9,“带锐音符的拉丁文小写字母E”。正如Daniel在他的回答中指出的,您可以通过首先对这些不同字符串进行规范化来检查它们的语义等价性。

以下是我将如何解决您的问题:

#!/usr/bin/python3

import sys
import unicodedata

with open('testmissingfiles', 'r') as fp:
    list1 = [line.strip() for line in fp]
with open('testfilesindata','r') as fp:
    list2 = [line.strip() for line in fp]

word1 = list1[0]
word2 = list2[0]

if word1 == word2:
    print("%s and %s are identical"%(word1, word2))
elif unicodedata.normalize('NFC', word1) == unicodedata.normalize('NFC', word2):
    print("%s and %s look the same, but use different code poitns"%(word1, word2))
else:
    print("%s and %s are unrelated"%(word1, word2))
全卜霸
2023-03-14

使用unicodedata。normalize将to字符串规格化为相同的标准格式

import unicodedata

encoded1 = unicodedata.normalize('NFC', word1.decode('utf8'))
encoded2 = unicodedata.normalize('NFC', word2.decode('utf8'))
 类似资料:
  • 问题内容: 我注意到我正在编写的Python脚本表现得很松散,并将其追溯到无限循环,其中循环条件为。在调试器中运行它,结果发现那条线实际上是。当我将其更改为!=’‘而不是时,它工作正常。 另外,即使比较或值,通常还是最好还是默认使用吗?我一直喜欢使用,因为我发现它在美学上更令人愉悦和pythonic(这就是我陷入这个陷阱的方式…),但是我想知道是否打算仅在你关心找到两个对象时才保留它?具有相同ID

  • 问题内容: 问题很简单。JAVA中是否有任何函数可以比较两个字符串并在忽略重音字符的情况下返回true? 即 回报相等。 谢谢 问题答案: 我认为您应该使用Collat​​or类。它允许您设置强度和区域设置,并将适当地比较字符。 从Java 1.6 API中: 您可以设置“整理器”的“强度”属性来确定在比较中被视为重要的差异水平。提供了四个优势:主要,次要,高等教育和同等优势。语言功能的优势确切分

  • 我无法使用以下代码比较两个字符串: 我有一个名为“gender”的字符串,它将以“male”或“fomen”作为其值。 这不起作用,所以我尝试了以下几种: 又一次,没有奏效。请告诉我如何使用if语句比较字符串值。

  • 我已经声明了一个实现可比较接口和compareTo方法的类,使用employee ID比较两个员工。创建的类对象插入数组列表。现在,当我使用collections.sort(arrayList对象)时,它工作得很好。我对collective和comparator接口之间的比较有何不同感到困惑。我想知道如何在纯粹由数字组成的employee id字符串和其他字符串employee id之间进行比较,

  • 为了使事情清楚,第一个是希腊语'β',第二个是拉丁语'B'。 当然,python给出False作为输出是正确的,但是对于我正在工作的脚本来说,我需要这样的字符来计算相同的值。尝试了几种编码/解码操作,但仍然算作不同的操作。有什么想法吗?

  • 主要内容:equals() 方法,equalsIgnoreCase() 方法,equals()与==的比较,compareTo() 方法字符串比较是常见的操作,包括比较相等、比较大小、比较前缀和后缀串等。 在 Java 中,比较字符串的常用方法有 3 个:equals() 方法、equalsIgnoreCase() 方法、 compareTo() 方法。下面详细介绍这 3 个方法的使用。 equals() 方法 equals() 方法将逐个地比较两个字符串的每个字符是否相同。如果两个字符串具有相