Python 如何检查字符串是否包含不在列表中的字符?

Python 如何检查字符串是否包含不在列表中的字符?,python,python-3.x,Python,Python 3.x,我有个问题。如何检查python字符串是否包含不在给定列表中的字符 以下是列表(集合): set(“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz012456789-。) 使用any为字符串的每个字符检入集合 SET=SET(“abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzo123456789-。” s=“123#” 打印(任何(x未设置为x英寸s)) 在验证字符串时,我总是遵从正

我有个问题。如何检查python字符串是否包含不在给定列表中的字符

以下是列表(集合):

set(“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz012456789-。)
  • 使用
    any
    为字符串的每个字符检入集合
SET=SET(“abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzo123456789-。”
s=“123#”
打印(任何(x未设置为x英寸s))

在验证字符串时,我总是遵从正则表达式

要创建集合,请将集合中的所有字符括在
[]
中。 要检查字符串是否包含任何不在集合中的字符,请在开头添加
^
。 要检查字符串是否包含一个或多个集合成员,请附加
+

根据此信息,检查字符串是否包含除{a,b,c,d}以外的任何字符的正则表达式如下所示:

[^abcd]+
(注意这是区分大小写的)

要在python中使用正则表达式,
import re
re.search(pattern,string,flags=0)
方法将在整个字符串中查找您给出的模式


可以找到有关python中正则表达式的更多信息。可以找到一个简单的正则表达式测试器。

您想测试字符串中的字符是否是给定字符集的子集。这在Python中很简单,因为比较不同解决方案的运行时

import timeit

search_strings = [
    '"#12"',                     # short string, early match
    '"#1234567"',                # longer string, early match
    '"1234567#"',                # longer string, late match
    '"123" * 100 + "#"',         # long string, late match
    '"123#" * 100',              # long string early match
]

algorithms = [
    ("r.search(s)", 's={};import re; r = re.compile(r"[^-.\w]")'),
    ("set(s) - SET", 's={};SET=frozenset("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._")'),
    ("any(x not in SET for x in s)", 's={};SET=frozenset("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._")'),
    ("SET.issuperset(s)", 's={};SET=frozenset("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._")'),
]

for alg, setup in algorithms:
    print alg
    for sstr in search_strings:
        print "%35s %.3f" % (sstr[:35], timeit.timeit(alg, setup.format(sstr)))
这将在我的机器上提供以下输出:

r.search(s)
                              "#12" 0.470
                         "#1234567" 0.514
                         "1234567#" 0.572
                  "123" * 100 + "#" 3.493
                       "123#" * 100 0.502
set(s) - SET
                              "#12" 0.566
                         "#1234567" 1.045
                         "1234567#" 1.075
                  "123" * 100 + "#" 7.658
                       "123#" * 100 10.170
any(x not in SET for x in s)
                              "#12" 0.786
                         "#1234567" 0.797
                         "1234567#" 1.475
                  "123" * 100 + "#" 27.266
                       "123#" * 100 1.087
SET.issuperset(s)
                              "#12" 0.466
                         "#1234567" 0.864
                         "1234567#" 0.896
                  "123" * 100 + "#" 7.512
                       "123#" * 100 10.199

我们发现正则表达式的解决方案是最快的。

将字符串转换为
,然后得到两个集之间的差异。如果这不是空的,则字符串包含不在集合中的字符。为什么以“更新问题以便只关注一个问题”的原因结束此操作?第二个问题在哪里?从答案中可以看出,这个问题是明确的。请重新打开。为什么不干脆
set(s)-set
?您只需要知道您的字符串是否包含不在s中的字符。使用any可以帮助提前停止。@bjorn取决于字符串。当
任何
在第一个非成员处停止时,您的方式总是构建整个集合。因此,您的速度较慢,例如
s=“#123456789”
。也许
SET.issuperset(s)
是最好的。@HeapOverflow它实际上并不依赖于字符串,唯一的退化情况是非法字符位于长字符串的前三个位置。如果不满足这些条件中的任何一个,例如,如果字符串较短:
set(“#12”)-set
any
版本快约25%。set实现也有一个可预测的运行时,因为它是用C实现的,而any循环是用Python实现的——更不用说set版本更容易理解了。@thebjorn这似乎确实是最快的。也可以使用
r“[^-.\w]”
,因为
\w
包括数字和下划线。还有
set.issuperset
,它接受任何iterable.Nevermind。我认为它会更快,因为它可以在第一个非成员处停止,而不是首先创建整个
s
的集合,但我只是检查了一下,然后就完成了。嘎。