我需要检查一些文字只包含小写字母a-z和逗号(“,”)。
在Python中执行此操作的最佳方法是什么?
答案 0 :(得分:16)
import re
def matches(s):
return re.match("^[a-z,]*$", s) is not None
这给了你:
>>> matches("tea and cakes")
False
>>> matches("twiddledee,twiddledum")
True
您可以使用re.compile优化一下:
import re
matcher = re.compile("^[a-z,]*$")
def matches(s):
return matcher.match(s) is not None
答案 1 :(得分:14)
import string
allowed = set(string.lowercase + ',')
if set(text) - allowed:
# you know it has forbidden characters
else:
# it doesn't have forbidden characters
使用sets执行它比使用for循环更快(特别是如果你想检查多个文本)并且在这种情况下它们比正则表达式更清晰。
可能比两套更快的替代方案是
allowed = string.lowercase + ','
if not all(letter in allowed for letter in text):
# you know it has forbidden characthers
这里有一些毫无意义的mtimeit
结果。 one
是生成器表达式,two
是基于集合的解决方案。
$ python -mtimeit -s'import scratch3' 'scratch3.one("asdfas2423452345sdfadf34")'
100000 loops, best of 3: 3.98 usec per loop
$ python -mtimeit -s'import scratch3' 'scratch3.two("asdfas2423452345sdfadf34")'
100000 loops, best of 3: 4.39 usec per loop
$ python -mtimeit -s'import scratch3' 'scratch3.two("asdfasasdfadsfasdfasdfdaf")'
100000 loops, best of 3: 3.51 usec per loop
$ python -mtimeit -s'import scratch3' 'scratch3.one("asdfasasdfadsfasdfasdfdaf")'
100000 loops, best of 3: 7.7 usec per loop
您可以看到基于setbased的表达式明显快于生成器表达式,并且具有较小的预期字母和成功条件。生成器表达式因故障而更快,因为它可以保释。这几乎是预期的,所以看到这些数字支持它很有意思。
我忘记的另一种可能性是混合方法。
not all(letter in allowed for letter in set(text))
$ python -mtimeit -s'import scratch3' 'scratch3.three("asdfasasdfadsfasdfasdfdaf")'
100000 loops, best of 3: 5.06 usec per loop
$ python -mtimeit -s'import scratch3' 'scratch3.three("asdfas2423452345sdfadf34")'
100000 loops, best of 3: 6.71 usec per loop
它减慢了最好的情况,但加快了最糟糕的情况。总而言之,您必须测试预期输入样本的不同可能性。样本越广越好。
答案 2 :(得分:3)
import re
if not re.search('[^a-z\,]', yourString):
# True: contains only a-z and comma
# False: contains also something else
答案 3 :(得分:1)
不确定“包含”是什么意思,但这应该朝着你的方向发展:
reobj = re.compile(r"[a-z,]+")
match = reobj.search(subject)
if match:
result = match.group()
else
result = ""
答案 4 :(得分:1)
只需:
def alllower(s):
if ',' in s:
s=s.replace(',','a')
return s.isalpha() and s.islower()
最有效和最简单。
或一行:
lambda s:s.isalpha() or (',' in s and s.replace(',','a').isalpha()) and s.islower()
答案 5 :(得分:0)
#!/usr/bin/env python
import string
text = 'aasdfadf$oih,234'
for letter in text:
if letter not in string.ascii_lowercase and letter != ',':
print letter
答案 6 :(得分:0)
字符a -z由字节97-122表示,ord(char)返回字符的字节值。以二进制形式读取文件并进行匹配就足够了。
f = open("myfile", "rb")
retVal = False
lowerAlphabets = range(97, 123)
try:
byte = f.read(1)
while byte != "":
# Do stuff with byte.
byte = f.read(1)
if byte:
if ord(byte) not in lowerAlphabets:
retVal = True
break
finally:
f.close()
if retVal:
print "characters not from a - z"
else:
print "characters from a - z"