2

Basically, I am trying to extract text between two strings within a loop as one of the two words changes after the information is extracted.

so for example, the string is:

string = alpha 111 bravo 222 alpha somethingA end, 333 bravo somethingB end 444 alpha 555 bravo

So I want to extract the text between alpha and end and then bravo and end. I have quite a few of these unique words in my file so I have a list and a counter to go through them. See the code below:

string = 'alpha 111 bravo 222 alpha somethingA end, 333 bravo somethingB end 444 alpha 555 bravo'
words = ['alpha', 'bravo'] #there will be more words here
counter = 0
stringOut = ''
#going through the list of words
while counter < len(words):

    firstWord = words[counter]
    lastWord = 'end'
    data = string[string.find(firstWord)+len(firstWord):string.find(lastWord)].strip()
    #this will give the text between the first ocurrance of "alpha" and "end"
    #since I want just the smallest string between "alpha" and "end", I use another    
    #while loop
    #to see if firstWord occurs again

    while firstWord in data:

        ignore,ignore2,data = data.partition(str(firstWord))
        counter = counter + 1 

    stringOut += str(data) + str('\n')
print('output string is \n' + str(stringOut))
#this code gives the correct output for the text between the first word ("alpha") and 
#"end".
#but when the list moves to the next string "bravo", it takes the text between the 
#first "bravo"
#and the "end" that was associated with the information required for "alpha" 
#("somethingA")

Any suggestions appreciated. Many thanks

4

3 回答 3

3

我将您的请求变成了一个方法/函数(迭代器)。我希望这可以帮助你 :)

string = 'alpha 111 bravo 222 alpha somethingA end, 333 bravo somethingB end 444 alpha 555 bravo'
words = ['alpha', 'bravo']

def method(string, words, end_word):
    segments = string.split(end_word)
    counter = 0
    while counter < len(words):
        data = segments[counter].split(words[counter])[-1]
        counter += 1
        yield data.strip()

for r in method(string, words, 'end'):
    print r

>>> 
somethingA
somethingB

注意:如果正在向前解析字符串并且永远不需要回头看,则此解决方案有效。

请注意,如果没有您的进一步输入,我不知道如何限制这一点,但目前,单词的长度必须等于或小于'end_word'字符串中的数量。

于 2013-02-04T11:00:13.183 回答
2

只需使用正则表达式

import re

string = 'alpha 111 bravo 222 alpha somethingA end, 333 bravo somethingB end 444 alpha 555 bravo'
words = ['alpha', 'bravo'] #there will be more words here

for word in words:
    expr = re.compile(r'.*' + word + '(.+?)end');
    out = expr.findall(string)
    print word + " => " + str(out[0])

输出:

>>> 
alpha =>  somethingA 
bravo =>  somethingB 
于 2013-02-04T10:55:38.667 回答
1

使用您的新子集:

string = 'alpha bravo ... alpha charlie somethingAC end ... ... bravo delta somethingBD end alpha ... bravo ...'
words = ['alpha','bravo','charlie','delta']

def method(string, words, end_word, single=True):
    segments = string.split(end_word)
    for word in words:
        for segment in segments:
            if word in segment:
                data = segment.split(word)[-1]
                yield (word, data.strip())
                if single:
                    break

注意新参数:single默认情况下,每个单词只会产生一个结果,但如果你愿意,它会在字符串的每个段中搜索每个单词,因为我不确定你想要什么,你以后可以随时删除它.

# each word only once
for r in method(string, words, 'end'):
    print r

>>> 
('alpha', 'charlie somethingAC')
('bravo', '... alpha charlie somethingAC')
('charlie', 'somethingAC')
('delta', 'somethingBD')

和:

# each word for each segment
for r in method(string, words, 'end', False):
    print r   

>>>
('alpha', 'charlie somethingAC')
('alpha', '... bravo ...')
('bravo', '... alpha charlie somethingAC')
('bravo', 'delta somethingBD')
('bravo', '...')
('charlie', 'somethingAC')
('delta', 'somethingBD')

作为奖励,我以列表理解的形式包含了这个生成器表达式:

def method1(string, words, end_word, single=True):
    return ([(word, segment.split(word)[-1]) for segment in string.split(end_word) if word in segment][:(1 if single else None)] for word in words)
于 2013-02-05T08:17:26.027 回答