14

我想比较两个字符串,以便比较应该忽略特殊字符的差异。那是,

嘿,这是一个测试

应与

嗨!这是一个测试“或”海这是一个测试

有没有办法在不修改原始字符串的情况下做到这一点?

4

8 回答 8

19

这会在进行比较之前删除标点符号和空格:

In [32]: import string

In [33]: def compare(s1, s2):
    ...:     remove = string.punctuation + string.whitespace
    ...:     return s1.translate(None, remove) == s2.translate(None, remove)

In [34]: compare('Hai, this is a test', 'Hai ! this is a test')
Out[34]: True
于 2013-05-10T03:54:04.557 回答
10
>>> def cmp(a, b):
...     return [c for c in a if c.isalpha()] == [c for c in b if c.isalpha()]
... 
>>> cmp('Hai, this is a test', 'Hai ! this is a test')
True
>>> cmp('Hai, this is a test', 'Hai this is a test')
True
>>> cmp('Hai, this is a test', 'other string')
False

这会创建两个临时列表,但不会以任何方式修改原始字符串。

于 2013-05-10T03:53:49.240 回答
1

为了比较任意数量的字符串的字母等价性,

def samealphabetic(*args):
    return len(set(filter(lambda s: s.isalpha(), arg) for arg in args)) <= 1

print samealphabetic('Hai, this is a test',
                     'Hai ! this is a test',
                     'Hai this is a test')

哪个打印True。应该<=根据你想要返回的没有参数而改变。

于 2013-05-10T04:30:25.890 回答
1

通常,您会替换您希望忽略的字符,然后比较它们:

import re
def equal(a, b):
    # Ignore non-space and non-word characters
    regex = re.compile(r'[^\s\w]')
    return regex.sub('', a) == regex.sub('', b)

>>> equal('Hai, this is a test', 'Hai this is a test')
True
>>> equal('Hai, this is a test', 'Hai this@#)($! i@#($()@#s a test!!!')
True
于 2013-05-10T03:53:56.180 回答
0

也许您可以先删除两个字符串中的特殊字符,然后进行比较。

在您的示例中,特殊字符是 ',','!' 和空间。

所以对于你的字符串:

a='Hai, this is a test'
b='Hai ! this is a test'
tempa=a.translate(None,',! ')
tempb=b.translate(None,',! ')

然后你可以比较 tempa 和 tempb。

于 2013-05-10T03:54:40.427 回答
0

由于您提到您不想修改原始字符串,因此您也可以就地执行操作,而无需任何额外空间。

>>> import string
>>> first = "Hai, this is a test"
>>> second = "Hai ! this is a test"
>>> third = "Hai this is a test"
>>> def my_match(left, right):
    i, j = 0, 0
    ignored = set(string.punctuation + string.whitespace)
    while i < len(left) and j < len(right):
        if left[i] in ignored:
            i += 1
        elif right[j] in ignored:
            j += 1
        elif left[i] != right[j]:
            return False
        else:
            i += 1
            j += 1
    if i != len(left) or j != len(right):
        return False
    return True

>>> my_match(first, second)
True
>>> my_match(first, third)
True
>>> my_match("test", "testing")
False
于 2013-05-10T03:59:51.617 回答
0

Python 3.* 的解决方案

root给出的解决方案兼容Python 2.7但不兼容Python 3。 *

这里有一些快速收据。

  1. 使用相同的解决方案,但针对 Python 3 进行了转换。* translate 函数现在只需要一个参数,它是要删除的序数(整数)字符的映射表。

导入字符串

    def compare(s1, s2):
        remove = string.punctuation + string.whitespace
        mapping = {ord(c): None for c in remove}
        print(f'Mapping: \n{mapping}')
        return s1.translate(mapping) == s2.translate(mapping)

    check = compare('Hai, this is a test', 'Hai ! this is a test')
    print(check)

文献资料

于 2021-10-14T03:27:12.963 回答
-1

使用Levenshtein 度量来测量两个字符串之间的距离。按分数对字符串比较进行排名。选择前n 个匹配项。

于 2013-05-10T03:57:11.843 回答