检查字符串的任何(全部)字符是否在给定范围内

2024-04-24 05:48:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含unicode符号(西里尔文)的字符串:

myString1 = 'Австрия'
myString2 = 'AustriЯ'

我想检查字符串中的所有元素是否都是英语(ASCII)。 现在我使用一个循环:

^{pr2}$

所以如果我找到第一个非英语元素,我就会打破这个循环。但是对于给定的示例,您可以看到字符串的末尾可以包含许多英文符号和unicode。这样我就可以检查整根弦了。此外,如果所有的字符串都是英文的,我仍然会检查每个字符。在

有没有更有效的方法?我在想的是:

if any(myString[:]) is not in range(65,91)

Tags: 方法字符串元素示例ifasciiunicode符号
3条回答

另一种方法,正如@schwobaseggl建议的那样,但使用全套方法:

import string
ascii = string.ascii_uppercase + string.ascii_lowercase
if set(my_string).issubset(ascii):
    #myString is ascii

您可以通过使用setO(1)包含检查)来加快检查速度,特别是如果您要检查同一范围的多个字符串,因为初始集创建也需要一次迭代。然后您可以使用^{}作为早期中断的迭代模式,它比^{}更适合这里:

import string

ascii = set(string.ascii_uppercase)
ascii_all = set(string.ascii_uppercase + string.ascii_lowercase)

if all(x in ascii for x in my_string1):
    # my_string1 is all ascii

当然,任何all结构都可以通过DeMorgan's Law转换为any

^{pr2}$

更新:

正如Artyer所指出的,一个好的基于纯集的方法不需要完全迭代:

if ascii.issuperset(my_string1):
    # my_string1 is all ascii

re似乎很快:

import re

# to check whether any outside ranges (->MatchObject) / all in ranges (->None)
nonletter = re.compile('[^a-zA-Z]').search

# to check whether any in ranges (->MatchObject) / all outside ranges (->None)
letter = re.compile('[a-zA-Z]').search

bool(nonletter(myString1))
# True

bool(nonletter(myString2))
# True

bool(nonletter(myString2[:-1]))
# False

OP的两个例子和一个积极的例子的基准(set是@schwobaseggl setset是@DanielSanchez):

^{pr2}$

基准代码:

import types
from timeit import timeit
import re
import string
import numpy as np

def mnsd(trials):
    return '{:1.8f} \u00b1 {:10.8f} \u00b5s'.format(np.mean(trials), np.std(trials))

nonletter = re.compile('[^a-zA-Z]').search
letterset = set(string.ascii_letters)

def f_re(stri):
    return not nonletter(stri)

def f_set(stri):
    return all(x in letterset for x in stri)

def f_setset(stri):
    return set(stri).issubset(letterset)

for stri in ('Австрия', 'AustriЯ', 'tralala'):
    ref = f_re(stri)
    print(stri)
    for name, func in list(globals().items()):
        if not name.startswith('f_') or not isinstance(func, types.FunctionType):
            continue
        try:
            assert ref == func(stri)
            print("{:16s}".format(name[2:]), mnsd([timeit(
                'f(stri)', globals={'f':func, 'stri':stri}, number=1000) * 1000 for i in range(1000)]))

        except:
            print("{:16s} apparently failed".format(name[2:]))

相关问题 更多 >