在Python中的两个指定单词之间查找文本,当两个单词中的一个更改时

时间:2013-02-04 10:44:00

标签: python

基本上,我试图在循环中的两个字符串之间提取文本,因为提取信息后两个单词之一会发生变化。

所以例如,字符串是:

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

所以我想在alpha和end之间提取文本然后bravo和end。我的文件中有很多这些独特的单词,所以我有一个列表和一个计数器来完成它们。请参阅以下代码:

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")

任何建议表示赞赏。非常感谢

3 个答案:

答案 0 :(得分: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'的数量

答案 1 :(得分:2)

只需使用regex

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 

答案 2 :(得分: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)