You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python字符串find返回-1:lower方法引发的token定位异常及修复咨询

问题

我编写了一个函数用于接收字符串并返回各token的位置。当直接使用tokens = query_string.split()时函数运行正常,但改用query_string.lower().split()生成tokens后,调用原字符串的find方法,得到的第一个元组为(-1, 2),而非预期的(0, 3)。测试字符串为'This is a test',相关代码如下:

def token_position_list(query_string):
    """
    :param query_string: a string representing a query
    :return: a list of tuples, where each tuple holds the start and end positions of each token
    """
    token_positions = []
    tokens = query_string.lower().split()
    current_position = 0
    for token in tokens:
        start_position = query_string.find(token, current_position)
        end_position = start_position + len(token) - 1
        token_positions.append((start_position, end_position))
        current_position = end_position + 1
    return token_positions

原因分析

核心问题是大小写不匹配导致查找失败:

  • 原字符串的第一个token是This(首字母大写),但query_string.lower().split()生成的第一个token是全小写的this。
  • Python的str.find()方法是区分大小写的,在原字符串中找不到全小写的this,因此返回-1。后续计算end_position = -1 + 4 - 1 = 2,就出现了错误的(-1, 2)元组。
  • 后面的is、a、test因为原字符串中本身就是小写,所以能正常匹配到对应位置。

修复方案

根据实际需求,有两种可行的修复方式:

方案1:不区分大小写查找token位置(适合需要忽略大小写匹配的场景)

使用正则表达式实现不区分大小写的查找,确保能匹配到原字符串中大小写不同的token:

import re

def token_position_list(query_string):
    token_positions = []
    tokens = query_string.lower().split()
    current_position = 0
    for token in tokens:
        # 用正则查找不区分大小写的匹配,从当前位置开始
        match = re.search(re.escape(token), query_string[current_position:], re.IGNORECASE)
        if match:
            start_position = current_position + match.start()
            end_position = start_position + len(token) - 1
            token_positions.append((start_position, end_position))
            current_position = end_position + 1
        else:
            # 处理找不到的情况,可根据需求调整逻辑
            token_positions.append((-1, -1))
    return token_positions

方案2:保留原始token拆分(适合需要严格对应原字符串token的场景)

先拆分原始字符串的token,再按需转小写,直接用原始token查找位置,避免大小写不匹配问题:

def token_position_list(query_string):
    token_positions = []
    current_position = 0
    # 直接拆分原始字符串的token
    for token in query_string.split():
        start_position = query_string.find(token, current_position)
        end_position = start_position + len(token) - 1
        token_positions.append((start_position, end_position))
        # 如果需要小写token,可在此生成
        lower_token = token.lower()
        current_position = end_position + 1
    return token_positions

两种方案测试输入'This is a test',都会返回预期的[(0, 3), (5, 6), (8, 8), (10, 13)]。

内容的提问来源于stack exchange,提问作者Helpme

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 14:20:31