【发布时间】:2011-09-13 13:01:49
【问题描述】:
在此处回答关于在某地寻找城市的问题后 用户提供的问题,我开始考虑最佳方法 当您的数据集有限时,在文本中搜索字符串。
in 和 find 匹配不想要的子字符串。常规
使用“单词边界”的表达式有效,但速度很慢。这
“标点符号”的方法似乎是一个候选,但有很多
标点符号characters 既可以出现在问题中,也可以出现在
一些以城市的名义(即“圣路易斯”中的一个时期)。
正则表达式可能是最好的通用解决方案,但我 好奇这是否可以使用其他技术来解决。
任务是:
在用户提供的英文文本中查找美国的城市 不分大小写。
我的代码深受http://www.python.org/doc/essays/list2str/的启发
#!/usr/bin/env python
import time
import re
def timing(f, n):
print f.__name__,
r = range(n)
t1 = time.clock()
for i in r:
f(); f(); f(); f(); f(); f(); f(); f(); f(); f()
t2 = time.clock()
print round(t2-t1, 6)
def f0():
'''broken since it finds sub-strings, e.g.
city "Erie" is found in "series"'''
Q = question.upper()
for c in cities:
c = c.upper()
if c in Q:
pass
def f1():
'''slow, but working'''
for c in cities:
re.search('\\b%s\\b' % c, question, re.IGNORECASE)
def f2():
'''broken, same problem as f0()'''
Q = question.upper()
for c in cities:
c = c.upper()
if Q.find(c) > 0:
pass
def f3():
'''remove all punctuation, and then search for " str " '''
Q = question.upper()
punct = ['.', ',', '(', ')', '"', '\n', ' ', ' ', ' ']
for p in punct:
Q = Q.replace(p, ' ')
for c in cities:
c = ' ' + c.upper() + ' '
for p in punct:
c = c.replace(p, ' ')
if c in Q:
pass
with open('cities') as fd:
cities = [line.strip() for line in fd]
with open('question') as fd:
question = fd.readlines()[0]
testfuncs = f0, f1, f2, f3
for f in testfuncs:
print f
timing(f, 20)
在我的旧笔记本电脑上,我得到以下结果
<function f0 at 0xb7730bc4>
f0 0.14
<function f1 at 0xb7730f7c>
f1 10.4
<function f2 at 0xb7730f44>
f2 0.15
<function f3 at 0xb7738684>
f3 0.61
如果有人想尝试一下我的测试数据,可以找到 here
【问题讨论】:
-
另一个有用的测试可能是使用预编译的正则表达式模式。
-
您可以编译一个大的正则表达式来匹配任何城市名称。看起来像
"(%s)" % "|".join(re.escape(c) for c in cities)。
标签: python algorithm search text