2.2 å—符串开头或结尾匹é…�¶
问题¶
ä½ éœ€è¦�通过指定的文本模å¼�去检查å—符串的开头或者结尾,比如文件å��å�Žç¼€ï¼ŒURL Schemeç‰ç‰ã€‚
解决方案¶
检查å—符串开头或结尾的一个简å�•方法是使用 str.startswith() 或者是 str.endswith() 方法。比如:
>>> filename = 'spam.txt'
>>> filename.endswith('.txt')
True
>>> filename.startswith('file:')
False
>>> url = 'http://www.python.org'
>>> url.startswith('http:')
True
>>>
å¦‚æžœä½ æƒ³æ£€æŸ¥å¤šç§�匹é…�å�¯èƒ½ï¼Œå�ªéœ€è¦�将所有的匹é…�项放入到一个元组ä¸åŽ»ï¼Œ
ç„¶å�Žä¼ ç»™ startswith() 或者 endswith() 方法:
>>> import os
>>> filenames = os.listdir('.')
>>> filenames
[ 'Makefile', 'foo.c', 'bar.py', 'spam.c', 'spam.h' ]
>>> [name for name in filenames if name.endswith(('.c', '.h')) ]
['foo.c', 'spam.c', 'spam.h'
>>> any(name.endswith('.py') for name in filenames)
True
>>>
下é�¢æ˜¯å�¦ä¸€ä¸ªä¾‹å�:
from urllib.request import urlopen
def read_data(name):
if name.startswith(('http:', 'https:', 'ftp:')):
return urlopen(name).read()
else:
with open(name) as f:
return f.read()
奇怪的是,这个方法ä¸å¿…é¡»è¦�输入一个元组作为å�‚数。
å¦‚æžœä½ æ�°å·§æœ‰ä¸€ä¸ª list 或者 set 类型的选择项,
è¦�ç¡®ä¿�ä¼ é€’å�‚æ•°å‰�先调用 tuple() 将其转æ�¢ä¸ºå…ƒç»„类型。比如:
>>> choices = ['http:', 'ftp:']
>>> url = 'http://www.python.org'
>>> url.startswith(choices)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: startswith first arg must be str or a tuple of str, not list
>>> url.startswith(tuple(choices))
True
>>>
讨论¶
startswith() å’Œ endswith() 方法æ��供了一个é�žå¸¸æ–¹ä¾¿çš„æ–¹å¼�去å�šå—符串开头和结尾的检查。
类似的æ“�作也å�¯ä»¥ä½¿ç”¨åˆ‡ç‰‡æ�¥å®žçŽ°ï¼Œä½†æ˜¯ä»£ç �看起æ�¥æ²¡æœ‰é‚£ä¹ˆä¼˜é›…。比如:
>>> filename = 'spam.txt'
>>> filename[-4:] == '.txt'
True
>>> url = 'http://www.python.org'
>>> url[:5] == 'http:' or url[:6] == 'https:' or url[:4] == 'ftp:'
True
>>>
ä½ å�¯ä»¥èƒ½è¿˜æƒ³ä½¿ç”¨æ£åˆ™è¡¨è¾¾å¼�去实现,比如:
>>> import re
>>> url = 'http://www.python.org'
>>> re.match('http:|https:|ftp:', url)
<_sre.SRE_Match object at 0x101253098>
>>>
è¿™ç§�æ–¹å¼�也行得通,但是对于简å�•的匹é…�实在是有点å°�æ��大用了,本节ä¸çš„æ–¹æ³•æ›´åŠ ç®€å�•并且è¿�行会更快些。
最��一下,当和其他�作比如普通数���相结�的时候 startswith() 和 endswith() 方法是很�错的。
比如,下é�¢è¿™ä¸ªè¯å�¥æ£€æŸ¥æŸ�ä¸ªæ–‡ä»¶å¤¹ä¸æ˜¯å�¦å˜åœ¨æŒ‡å®šçš„æ–‡ä»¶ç±»åž‹ï¼š
if any(name.endswith(('.c', '.h')) for name in listdir(dirname)):
...