Python regex打印包含两个标记类的所有句子

2024-04-19 20:05:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望在XML文件中阅读,找到包含标记<emotion>和标记<LOCATION>的所有句子,然后将这些句子打印到一个唯一的行中。下面是代码示例:

import re

text = "Cello is a <emotion> wonderful </emotion> parakeet who lives in <LOCATION> Omaha </LOCATION>. He is the <emotion> best </emotion> singer <pronoun> I </pronoun> have ever heard." 

out = open('out.txt', 'w')

for match in re.findall(r'(?:(?<=\.)\s+|^)((?=(?:(?!\.(?:\s|$)).)*?\bwonderful(?=\s|\.|$))(?=(?:(?!\.(?:\s|$)).)*?\bomaha(?=\s|\.|$)).*?\.(?=\s|$))', text, flags=re.I):
    line = ''.join(str(x) for x in match)
    out.write(line + '\n')

out.close()

这里的regex获取所有包含“wonderful”和“omaha”的句子,并返回:

Cello is a <emotion> wonderful </emotion> parakeet who lives in <LOCATION> Omaha </LOCATION>.

这很完美,但是我真的想打印所有同时包含<emotion>和{}的句子。但是,由于某些原因,当我将上面的regex中的“wonderful”替换为“emotation”时,regex无法返回任何输出。因此,以下代码不会产生结果:

^{pr2}$

我的问题是:如何修改正则表达式,以便只获取同时包含<emotion>和{}的句子?在这个问题上,我将非常感激别人能提供的任何帮助。在

(值得一提的是,我也在用beauthoulsoup解析我的文本,但我想在认输之前给正则表达式最后一次机会。)


Tags: 代码textin标记reislocationout
3条回答

您的问题似乎是您的regex在匹配的单词后面需要一个空格(\s),如下所示:

emotion(?=\s|\.|$)

因为当它是标记的一部分时,它后面跟一个>,而不是一个空格,所以由于lookahead失败,所以找不到匹配项。要解决这个问题,您只需在情绪之后添加>,例如:

^{pr2}$

经过测试,这似乎解决了您的问题。确保和对待“位置”相似:

for match in re.findall(r'(?:(?<=\.)\s+|^)((?=(?:(?!\.(?:\s|$)).)*?\bemotion>(?=\s|\.|$))(?=(?:(?!\.(?:\s|$)).)*?\bLOCATION>(?=\s|\.|$)).*?\.(?=\s|$))', text, flags=re.I):
    line = ''.join(str(x) for x in match)

我刚刚发现正则表达式可能被完全绕过。要查找(并打印)包含两个标记类的所有句子,可以使用一个简单的for循环。如果这可能会帮助那些在我发现自己的地方找到自己的人,我会发布我的代码:

# read in your file
f = open('sampleinput.txt', 'r')

# use read method to convert the read data object into string
readfile = f.read()

#########################
# now use the replace() method to clean data
#########################

# replace all \n with " "
nolinebreaks = readfile.replace('\n', ' ')

# replace all commas with ""
nocommas = nolinebreaks.replace(',', '')

# replace all ? with .
noquestions = nocommas.replace('?', '.')

# replace all ! with .
noexclamations = noquestions.replace('!', '.')

# replace all ; with .
nosemicolons = noexclamations.replace(';', '.')

######################
# now use replace() to get rid of periods that don't end sentences
######################

# replace all Mr. with Mr
nomisters = nosemicolons.replace('Mr.', 'Mr') 

#replace 'Mrs.' with 'Mrs' etc. 

cleantext = nomisters

#now, having cleaned the input, find all sentences that contain your two target words. To find markup, just replace "Toby" and "pipe" with <markupclassone> and <markupclasstwo>

periodsplit = cleantext.split('.')
for x in periodsplit:
    if 'Toby' in x and 'pipe' in x:
        print x

如果我不明白你想做的是删除<emotion> </emotion> <LOCATION></LOCATION>??在

如果这就是你想做的,你可以这么做

import re

text = "Cello is a <emotion> wonderful </emotion> parakeet who lives in <LOCATION> Omaha </LOCATION>. He is the <emotion> best </emotion> singer I have ever heard." 

out = open('out.txt', 'w')

def remove_xml_tags(xml):
    content = re.compile(r'<.*?>')
    return content.sub('', xml)

data = remove_xml_tags(text)

out.write(data + '\n')

out.close()

相关问题 更多 >