Python:查找字符串中的子字符串并返回子字符串的索引

84

我有:

  • 一个函数:def find_str(s, char)

  • 和一个字符串:"Happy Birthday",

我希望输入"py"并返回3,但我一直得到了2的结果。

代码:

def find_str(s, char):
    index = 0           
    if char in s:
        char = char[0]
        for ch in s:
            if ch in s:
                index += 1
            if ch == char:
                return index

    else:
        return -1

print(find_str("Happy birthday", "py"))

不确定出了什么问题!


2
我不确定这段代码哪里出了问题。你用 char = char[0] 摧毁了你的第二个参数。在此之后,你的第二个参数只是 "p",然后它在位置 2(H,a,p)找到了一个匹配项,就这样结束了。 - Nikhil VJ
7个回答

240

字符串对象上有一个内置的方法find

s = "Happy Birthday"
s2 = "py"

print(s.find(s2))

Python是一种“自带电池”的语言,已经有代码可以完成大部分你想要的事情(无论你想做什么)... 除非这是作业 :)
如果找不到字符串,find会返回-1。

2
@Kev1n91 这真的很奇怪,它没有被接受。 - Ver Nick
原回答被接受后,我回答了这个问题。我碰巧看到它,想要加上我的意见。 - demented hedgehog
它没有被接受,因为@Tyler不能使用str.find或str.index。 - pdaawr

28

理想情况下,您应该像demented hedgehog所说的那样使用str.findstr.index。但是您说您不能使用......

您的问题在于代码仅搜索您要查找的字符串的第一个字符,而这个字符在索引2处。

您的基本意思是如果char[0]s中,则增加index直到ch == char[0],当我测试时返回3,但仍然不正确。这是一种解决方法。

def find_str(s, char):
    index = 0

    if char in s:
        c = char[0]
        for ch in s:
            if ch == c:
                if s[index:index+len(char)] == char:
                    return index

            index += 1

    return -1

print(find_str("Happy birthday", "py"))
print(find_str("Happy birthday", "rth"))
print(find_str("Happy birthday", "rh"))
它产生了以下输出:
3
8
-1

我需要编写一个算法来执行 .find 函数。不幸的是,我不能直接使用它! - Tyler
@Tyler,我编辑了我的回答,因为实际上并没有回答你的问题。 - Eric Fortin
有一个更好的方法,就像@demented hedgehog建议的那样。这应该是被接受的答案。 - Kev1n91
@Kev1n91 我知道,而且我在我的答案中也说了,但是OP评论说他不能使用它。 - Eric Fortin

12

正则表达式中还有一个选项,即search方法。

import re

string = 'Happy Birthday'
pattern = 'py'
print(re.search(pattern, string).span()) ## this prints starting and end indices
print(re.search(pattern, string).span()[0]) ## this does what you wanted

顺便提一下,如果您想查找模式的所有出现而不仅仅是第一个,可以使用finditer方法

import re

string = 'i think that that that that student wrote there is not that right'
pattern = 'that'

print([match.start() for match in re.finditer(pattern, string)])

它将打印出所有匹配的起始位置。


3

在@demented hedgehog关于使用find()的答案基础上进行补充

效率而言

在调用find()之前,先检查s1是否在s2中可能是值得的。
如果您知道大多数情况下s1不是s2的子字符串,则这可能更有效

由于in运算符非常高效

 s1 in s2

将其转换为以下代码可以更加高效:

index = s2.find(s1)

to

index = -1
if s1 in s2:
   index = s2.find(s1)

find()返回-1很多次时,这将非常有用。

在我的算法中,由于find()被多次调用,我发现它运行速度大大加快,因此认为值得一提。


2
这里有一个简单的方法:
my_string = 'abcdefg'
print(text.find('def'))

输出:

3

如果子字符串不存在,你将会得到-1。 例如:

my_string = 'abcdefg'
print(text.find('xyz'))

输出:

-1

有时候,如果子字符串不存在,您可能想要抛出异常:

my_string = 'abcdefg'
print(text.index('xyz')) # It returns an index only if it's present

输出:

追溯(最近的调用):

文件 "test.py",第6行,在 print(text.index('xyz'))

ValueError: 未找到子字符串


1

我来晚了,正在寻找同样的内容,因为“in”无效,所以我刚刚创建了以下内容。

def find_str(full, sub):
    index = 0
    sub_index = 0
    position = -1
    for ch_i,ch_f in enumerate(full) :
        if ch_f.lower() != sub[sub_index].lower():
            position = -1
            sub_index = 0
        if ch_f.lower() == sub[sub_index].lower():
            if sub_index == 0 :
                position = ch_i

            if (len(sub) - 1) <= sub_index :
                break
            else:
                sub_index += 1

    return position

print(find_str("Happy birthday", "py"))
print(find_str("Happy birthday", "rth"))
print(find_str("Happy birthday", "rh"))

which produces

3
8
-1

在不需要大小写敏感的情况下,可以删除lower()函数。

1

虽然没有直接回答问题,但我最近遇到了一个类似的问题,被要求计算给定字符串中子字符串重复出现的次数。这是我编写的函数:

def count_substring(string, sub_string):
    cnt = 0
    len_ss = len(sub_string)
    for i in range(len(string) - len_ss + 1):
        if string[i:i+len_ss] == sub_string:
            cnt += 1
    return cnt

find()函数可能仅返回第一次出现的索引。将索引存储在计数位置可以为我们提供子字符串在字符串中重复出现的不同索引集。

免责声明:我对Python编程非常陌生。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接