如何尽快在另一个字符串中查找特定字符串?

时间:2015-07-18 01:19:36

标签: python indexing

我想知道是否有更好/更好/更快的方法来解决以下问题。

  

如果给定的字符串包含“abc”的外观,则返回True,其中abc不直接以句点(。)开头。所以“qabc”很重要,但“r.abc”不算数。

我的解决方案是:

def abc_there(string):
    tmp = 0
    for i in xrange(len(string)):
        if string[i:i+3] == "abc" and string[i-1] != ".":
            tmp += 1
    return tmp > 0

修改

只是为了澄清:

“。abc” - >假

“。abcabc” - >真

只有句号右侧旁边的实例才会被删除。

4 个答案:

答案 0 :(得分:5)

正则表达式是完成此任务的完美工具:

>>> import re
# Test if it contains a match
>>> bool(re.search(r'(?:^|[^.])(abc)', 'testabc funcabc'))
True
>>> bool(re.search(r'(?:^|[^.])(abc)', '.abc'))
False

# Count the number of occurrences
>>> re.findall(r'(?:^|[^.])(abc)', 'abc testabc func.abc')
['abc', 'abc']
>>> len(re.findall(r'(?:^|[^.])(abc)', 'abc testabc func.abc'))
2

有关详细信息,请参阅Python documentation on the re module

答案 1 :(得分:5)

有一种不太直接的方法来解决这个问题 而且它也稍微快一些。我的代码:

def xyz_there(string):
    return string.count(".abc") != string.count("abc")

这是有效的,因为如果有一个字符串传递为“abc.abc”, “.abc”计数为1 但是abc计数是2 但是,如果字符串只是“fd.abc.abc”。 它将返回False。

为了证明它更快,我前往IPython。

In [1]: def abc_there(string):
 ...:       tmp = 0
 ...:       for i in xrange(len(string)):
 ...:           if string[i:i+3] == "abc" and string[i-1] != ".":
 ...:               tmp += 1
 ...:       return tmp > 0

In [2]: timeit abc_there("nghkabc")
Out[2]: 1000000 loops, best of 3: 310 ns per loop

In [3]: def abc_there(string):
...:        return string.count(".abc") != string.count("abc")

In [4]: timeit abc_there("nghkabc")
Out[4]: 1000000 loops, best of 3: 296 ns per loop

296ns< 310ns所以我的解决方案更快一点。

答案 2 :(得分:1)

对于这种类型的东西,正则表达式可能是要走的路。但是,如果你要使用你已经拥有的东西,你仍然不够懒惰。

def abc_there(string):
    if string[:3] == "abc": return True #case "abc" at start of string
    for i in xrange(1,len(string)):
        if string[i:i+3] == "abc" and string[i-1] != ".":
            return True #Hah! found something. I get to leave early!
    #if we make it out of the loop without finding something
    return False

请注意,如果找到任何匹配项,您将返回True;如果找不到匹配项,则只会到达return False。通常,如果您正在编写一个在迭代器中检查某些内容的函数,那么您希望尽早停止并返回。 (顺便提一句,内置anyall就是为了做到这一点。)

哦,我想,如果您在迭代器中检查过某些内容,请考虑使用anyall:P

答案 3 :(得分:0)

import re
re.match(r"abc|.*[^.]abc", string) 

或速度:

import re
r = re.compile(r"abc|.*[^.]abc")
r.match(string)
r.match(string2)