如何检查字符串是否包含字母表中的任何字母?


82

什么是最好的纯Python实现,以检查字符串是否包含字母表中的任何字母?

string_1 = "(555).555-5555"
string_2 = "(555) 555 - 5555 ext. 5555

哪里string_1False因为没有字母而string_2返回True,而会因为有了字母而返回。


2
是否应仅限于英语a / z字母?是否应考虑其他字母(例如德语)中的“特殊”字符?
科奇2012年

您是否有可能收到unicode?还是只是普通的ascii罗马字母?
神户约翰

那里的时间不错:)无论如何,如果您需要帮助测试带有Unicode字符的字符串,请检查一下类似的问题。
科比

1
仅限于英语a / z字母和仅普通的罗马字母:)
贾斯汀·帕佩兹

Answers:


123

正则表达式应该是一种快速的方法:

re.search('[a-zA-Z]', the_string)

1
谢谢JBernado,这是我最终要做的,它可以完美地完成我需要做的事情。
贾斯汀·帕佩兹

30
正则表达式当然似乎有点矫kill过正。any(c.isalpha() for c in string_1)是美味的Pythonic。
Jollywatt

5
@约瑟夫不,不是。这个正则表达式比您的表达式更具可读性。另外,这isalpha甚至意味着什么?将Python 2与Python 3进行比较时,这将具有完全不同的行为。中文是字母的一部分吗?如果不是这样,您就盲目地将其与Python 3上的生成器匹配(或Unicode字符串为Python 2!)。如果您要使用Pythonic,则为:Simple is better than complex.。并检查上面OP的评论:他只希望匹配罗马字母。
JBernardo

1
我认为约瑟夫的答案很容易理解,而且肯定比其他输入要快。另外,您不必记住re.search中参数的顺序
Hinton

11
如果其他人想知道返回值是什么,则可以找到一个Match对象,如果有匹配项,或者None没有匹配项。因此,这与if re.search(...模式兼容。
斯里尼

74

怎么样:

>>> string_1 = "(555).555-5555"
>>> string_2 = "(555) 555 - 5555 ext. 5555"
>>> any(c.isalpha() for c in string_1)
False
>>> any(c.isalpha() for c in string_2)
True

set(string_1)更有效吗?
里克·波吉

1
@Rik。您是说要在测试之前将string_1转换为集合?不,它不会更高效。可以保证至少处理一次所有字符,而我相信任何函数在遇到第一个错误时都会短路(停止)。
科比

这段代码会有点慢,因为它需要每个字符调用一个函数。转换为set可能会或可能不会减少函数调用,但会增加一些开销。
JBernardo

2
@JBernardo:timeit表明它比编译的正则表达式慢一个数量级,并且比未编译的正则表达式仅花费大约66%的时间。这完全在我的“我讨厌正则表达式”限制之内。
DSM '01年

1
当然:如果您使用“(555).555-5555 ext。5555” * 1000,由于短路,您将恢复到可比的速度。我更喜欢用Python编写而不是编写正则表达式,除非发现它们很琐碎,否则我很难调试它们,并且除非性能需求要求,否则我不会放弃编写清晰的Python。
DSM

27

您可以islower()在字符串上使用以查看它是否包含一些小写字母(以及其他字符)。orisupper()也检查是否包含一些大写字母:

下图:字符串中的字母:测试结果为true

>>> z = "(555) 555 - 5555 ext. 5555"
>>> z.isupper() or z.islower()
True

下图:字符串中没有字母:test得出false。

>>> z= "(555).555-5555"
>>> z.isupper() or z.islower()
False
>>> 

不要混淆,仅当所有字符都是字母时才isalpha()返回True,这不是您想要的。

请注意,Barm的回答很好地完成了我回答,因为我的问题处理得不好。


3
我喜欢这将测试它是否包含字母,而不仅仅是测试输入是否为全部字母。
Cornbeetle

@Cornbeetle是的,那种真正的答案后,所有的问题这些年来,感谢
让·弗朗索瓦·法布尔

很好的表达方式。效率如何?比正则表达式更好?
pnv

没有涉及到python循环,因此效率很高。我没有用正则表达式的初始化阶段比较,但我想这是稍快,特别是因为没有正则表达式的编译
让·弗朗索瓦·法布尔

13

我喜欢@jean-françois-fabre提供的答案,但答案不完整。
他的方法将起作用,但前提是文本仅包含小写或大写字母:

>>> text = "(555).555-5555 extA. 5555"
>>> text.islower()
False
>>> text.isupper()
False

更好的方法是先对字符串进行大写或小写,然后再检查。

>>> string1 = "(555).555-5555 extA. 5555"
>>> string2 = '555 (234) - 123.32   21'

>>> string1.upper().isupper()
True
>>> string2.upper().isupper()
False

8

您可以使用如下正则表达式:

import re

print re.search('[a-zA-Z]+',string)

2

我测试了上述每种方法,以确定给定字符串中是否包含任何字母,并找出标准计算机上每个字符串的平均处理时间。

约250 ns

import re

约3 µs

re.search('[a-zA-Z]', string)

约6 µs

any(c.isalpha() for c in string)

约850 ns

string.upper().isupper()


与所谓的相反,导入re所花费的时间可以忽略不计,并且即使对于相对较小的字符串,与迭代isalpha()相比,使用re进行搜索仅花费大约一半的时间。 因此,对于更大的字符串和更大的计数,re将显着提高效率。 但是将字符串转换为大小写并检查大小写(例如,upper()。isupper()lower()。islower()中的任何一个)在这里胜出。在每个循环中,它都比re.search()快得多,甚至不需要任何其他导入。



1
您还可以编译正则表达式以进行进一步的优化。alpha_regex = re.compile('[a-zA-Z]')之后alpha_regex.search(字符串)
Behdad Forghani

更不用说isalpha()不能很好地适用于多种语言。我之所以这样做是因为我想检查一个预期为韩文的字符串是否包含任何英文字母,并且isalpha()方法为每个韩文字符串返回True。
陈宇

0

您还可以另外执行此操作

import re
string='24234ww'
val = re.search('[a-zA-Z]+',string) 
val[0].isalpha() # returns True if the variable is an alphabet
print(val[0]) # this will print the first instance of the matching value

还要注意,如果变量val返回None。这意味着搜索未找到匹配项

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.