使用Python正则表达式解析文本文件中的标签

1 投票
2 回答
1045 浏览
提问于 2025-04-17 12:21

今天我得到了些帮助,但我还是搞不清楚我遇到问题的最后一部分。这个正则表达式搜索可以从打开的文件中找到所有匹配的内容。现在我需要做的是找出这些匹配内容来自文件的哪个部分。

每个部分都是用标签来打开和关闭的。比如说,一个标签是用 <opera> 开始,用 </opera> 结束。我想要做的是,当我找到一个匹配时,能够向后找到打开的标签,或者向前找到关闭的标签,并把这个标签的内容,比如“opera”,也包含在输出中。我的问题是,是否可以通过在正则表达式中添加一些内容来实现,或者有没有更好的方法?这是我已经很好用的代码:

text = open_file.read()
#the test string for this code is "NNP^CC^NNP"
grammarList = raw_input("Enter your grammar string: ");

tags = grammarList.split("^")
tags_pattern = r"\b" + r"\s+".join(r"(\w+)/{0}".format(tag) for tag in tags) + r"\b" 
# gives you r"\b(\w+)/NNP\s+(\w+)/CC\s+(\w+)/NNP\b"

from re import findall
print(findall(tags_pattern, text))

2 个回答

0

在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。比如说,可能会出现错误提示,或者程序运行不如预期。这时候,我们需要去寻找解决方案,通常可以在一些技术论坛上找到答案,比如StackOverflow。

在这些论坛上,很多人会分享他们的经验和解决方法。你可以看到他们描述的问题、提供的代码示例,以及他们是如何解决这些问题的。这些信息对初学者来说非常有帮助,因为它们可以让你更快地理解问题的本质,并找到合适的解决方案。

总之,遇到问题时,不要害怕去查找资料和请教他人,很多人都曾经历过类似的困扰,分享他们的经验可以帮助你更好地学习和成长。

from BeautifulSoup import BeautifulSoup

tags = """stuff outside<opera>asdfljlaksdjf lkasjdfl kajsdlf kajsdf stuff
<asdf>asdf</asdf></opera>stuff outside"""    

soup = BeautifulSoup(tags)

soup.opera.text
Out[22]: u'asdfljlaksdjf lkasjdfl kajsdlf kajsdf stuffasdf'

str(soup.opera)
Out[23]: '<opera>asdfljlaksdjf lkasjdfl kajsdlf kajsdf stuff
<asdf>asdf</asdf></opera>'
0

一种方法是找到你开始和结束的标签(比如说它们是 <opera></opera>),然后获取它们的位置,再把这些位置和 tags_pattern 的每个匹配项进行比较。这种方法使用了 finditer,它的功能类似于 findall,但它还会返回位置索引。可以这样做:

startTags = re.finditer("<opera>",text)
endTags   = re.finditer("</opera>",text)

matches = re.finditer(tags_pattern,text)

# Now, [m.start() for m in matches] gives the starting index into `text`.
# if <opera> starts at subindices 0, 1000, 2345
# and you get a match starting at subindex 1100,
#  then it's in the 1000-2345 block.
for m in matches:
    # find first
    sec = [i for i in xrange(len(startTags)) if i>startTags[i].start()]
    if len(sec)=0:
        print "err couldn't find it"
    else:
        sec = sec[0]
        print "found in\n" + text[startTags[sec].start():endTags[sec].end()]

(注意:你可以通过 m.group() 获取匹配到的文本。默认的 () 是组 0(也就是整个字符串),你可以用 m.group(i) 来获取第 i 个捕获组的内容。)

撰写回答