Как разбить строку по пробелам и сохранить смещения и длины слов

Мне нужно разбить строку на слова, но также получить начальное и конечное смещение слова. Так, например, если входная строка:

input_string = "ONE  ONE ONE   \t TWO TWO ONE TWO TWO THREE"

Я хочу получить:

[('ONE', 0, 2), ('ONE', 5, 7), ('ONE', 9, 11), ('TWO', 17, 19), ('TWO', 21, 23),
 ('ONE', 25, 27), ('TWO', 29, 31), ('TWO', 33, 35), ('THREE', 37, 41)]

У меня есть рабочий код, который делает это с помощью input_string.split и вызывает .index, но он медленный. Я попытался закодировать его, вручную перебирая строку, но это было еще медленнее. Есть ли у кого-нибудь быстрый алгоритм для этого?

Вот мои две версии:

def using_split(line):
    words = line.split()
    offsets = []
    running_offset = 0
    for word in words:
        word_offset = line.index(word, running_offset)
        word_len = len(word)
        running_offset = word_offset + word_len
        offsets.append((word, word_offset, running_offset - 1))

    return offsets

def manual_iteration(line):
    start = 0
    offsets = []
    word = ''
    for off, char in enumerate(line + ' '):
        if char in ' \t\r\n':
            if off > start:
                offsets.append((word, start, off - 1))
            start = off + 1
            word = ''
        else:
            word += char

    return offsets

При использовании timeit "using_split" является самым быстрым, за ним следует "manual_iteration", затем самым медленным на данный момент является использование re.finditer, как было предложено. ниже.

12
задан xorsyst 1 March 2012 в 17:12
поделиться