Python正则表达式未提取值-Python 3.x
我正在循环浏览一个非常大(~5GB)的文本文档,如下所示:Python正则表达式未提取值-Python 3.x,python,regex,python-3.x,beautifulsoup,nltk,Python,Regex,Python 3.x,Beautifulsoup,Nltk,我正在循环浏览一个非常大(~5GB)的文本文档,如下所示: <P ID=912> bird dog dog dog </P> <P ID=5> aardvark bird bird cat egret </P> <P ID=291> aardvark aardvark aardvark aardvark aardvark bird dog fish fish fish </P> <P ID=621> aar
<P ID=912>
bird
dog
dog
dog
</P>
<P ID=5>
aardvark
bird
bird
cat
egret
</P>
<P ID=291>
aardvark
aardvark
aardvark
aardvark
aardvark
bird
dog
fish
fish
fish
</P>
<P ID=621>
aardvark
aardvark
bird
dog
fish
fish
fish
</P>
<P ID=5>
bird
egret
egret
</P>
<P ID=1>
bird
</P>
其结果是:
Current paragraph Number: None
Current paragraph Number: None
Current paragraph Number: None
Current paragraph Number: None
Current paragraph Number: None
Current paragraph Number: None
然而,我希望它看起来像:
Current paragraph Number: 912
Current paragraph Number: 5
Current paragraph Number: 291
Current paragraph Number: 621
Current paragraph Number: 5
Current paragraph Number: 1
我需要如何更改:para\u id=re.match(,para)
编辑:
我也尝试过:
para_id=[i['id']表示汤中的i(para,'html.parser')。查找所有('p')]
但是这会产生一个空白的[]
,我不知道为什么我不能创建一个单一段落的汤
注意-我应该提到这是代码的一个最小示例。真正的程序要大得多,需要NLTK进行解析,因为我在停止字和文本标记化方面做了很多工作。一个可能的解决方案是在使用
NLTK
进行处理后,将您的输入传递到BeautifulSoup
:
from bs4 import BeautifulSoup as soup
results = [i['id'] for i in soup(content, 'html.parser').find_all('p')]
输出:
['912', '5', '291', '621', '5', '1']
['\nbird\ndog\ndog\ndog\n']
['\naardvark\nbird\nbird\ncat\negret\n']
['\naardvark\naardvark\naardvark\naardvark\naardvark\nbird\ndog\nfish\nfish\nfish\n']
['\naardvark\naardvark\nbird\ndog\nfish\nfish\nfish\n']
['\nbird\negret\negret\n']
['\nbird\n']
BeautifulSoup
使您能够使用soup.contents
访问段落内容:
for i in soup(content, 'html.parser').find_all('p'):
print(i.contents)
输出:
['912', '5', '291', '621', '5', '1']
['\nbird\ndog\ndog\ndog\n']
['\naardvark\nbird\nbird\ncat\negret\n']
['\naardvark\naardvark\naardvark\naardvark\naardvark\nbird\ndog\nfish\nfish\nfish\n']
['\naardvark\naardvark\nbird\ndog\nfish\nfish\nfish\n']
['\nbird\negret\negret\n']
['\nbird\n']
在findall()搜索中使用r'(?s)(.*?)
。ID
在捕获组1中,Content
在捕获组2中
范例
>>> input = """
... <P ID=912>
... bird
... dog
... dog
... dog
... </P>
...
... <P ID=5>
... aardvark
... bird
... bird
... cat
... egret
... </P>
...
... <P ID=291>
... aardvark
... aardvark
... aardvark
... aardvark
... aardvark
... bird
... dog
... fish
... fish
... fish
... </P>
...
... <P ID=621>
... aardvark
... aardvark
... bird
... dog
... fish
... fish
... fish
... </P>
...
... <P ID=5>
... bird
... egret
... egret
... </P>
...
... <P ID=1>
... bird
... </P>
... """
>>>
>>> import re
>>> p = re.compile(r'(?s)<P\s*ID\s*=\s*(\d+)\s*>(.*?)</P\s*>')
>>>
>>> ids = p.findall(input)
>>>
>>> i = 0
>>> ids_len = len(ids)
>>>
>>> while ( i < ids_len ):
... print(ids[i]) # The ID
... print(ids[i+1]) # The Content
... i += 2
...
('912', '\nbird\ndog\ndog\ndog\n')
('5', '\naardvark\nbird\nbird\ncat\negret\n')
('291', '\naardvark\naardvark\naardvark\naardvark\naardvark\nbird\ndog\nfish\nfish\nfish\n')
('621', '\naardvark\naardvark\nbird\ndog\nfish\nfish\nfish\n')
('5', '\nbird\negret\negret\n')
('1', '\nbird\n')
>>>
>>input=“”
…
…鸟
…狗
…狗
…狗
…
...
…
…土豚
…鸟
…鸟
…猫
白鹭
…
...
…
…土豚
…土豚
…土豚
…土豚
…土豚
…鸟
…狗
…鱼
…鱼
…鱼
…
...
…
…土豚
…土豚
…鸟
…狗
…鱼
…鱼
…鱼
…
...
…
…鸟
白鹭
白鹭
…
...
…
…鸟
…
... """
>>>
>>>进口稀土
>>>p=重新编译(r'(?s)(*?))
>>>
>>>ids=p.findall(输入)
>>>
>>>i=0
>>>ids_len=len(ids)
>>>
>>>而(i>>
您可以在何处捕获段落的文本,但
您应该捕获整个段落,包括P标记,
在您捕获段落Id之后,我在data.txt
中使用了您的简单代码:
从nltk.tokenize导入单词\u tokenize,RegexpTokenizer
进口稀土
def get_输入(文件路径):
f=打开(文件路径“r”)
content=f.read()
f、 close()#别忘了关闭文件
返回内容
def main():
myfile=get_输入(“data.txt”)
#下面是全文
p=r'.*?
'
段落=RegexpTokenizer(p)
para_id=0
对于段落标记化(myfile)中的段落:
#在这里,你就可以拿到身份证了
para_id=re.match(“”,para)
打印(“当前段落编号:{}”。格式(段落id.组(1)))
main()
输出:
Current paragraph Number: 912
Current paragraph Number: 5
Current paragraph Number: 291
Current paragraph Number: 621
Current paragraph Number: 5
Current paragraph Number: 1
您正在读取整个5 GB文件,我认为您应该使用generator,
如果您只需要打印段落Id:
import re
def main():
with open("data.txt") as f: # Using context manager to close resource
for line in f:
# and here just catch the ID
match = re.match("<P ID=(\d+)>", line)
if match:
print("Current paragraph Number: {}".format(match.group(1)))
main()
重新导入
def main():
将open(“data.txt”)作为f:#使用上下文管理器关闭资源
对于f中的行:
#在这里,你就可以拿到身份证了
match=re.match(“”,第行)
如果匹配:
打印(“当前段落编号:{}”。格式(match.group(1)))
main()
这将在不将整个5 GB加载到内存的情况下生成相同的结果。您可能只需要
re.search
而不是re.match
。不幸的是,将re.match
更改为re.search
会产生相同的结果。感谢您的建议。我从来没有使用过BeautifulSoup
,因此了解这一点很好。我如何在我提到的段落循环中使用它(真正的程序需要在段落中循环以进行一些文本解析和其他事情)@JerryM。请看我最近的编辑BeautifulSoup
使您能够利用soup.contents
属性访问标记下的所有子值。谢谢,我将尝试以我发布的for-loop格式运行此功能,然后返回给您。您可以发布示例吗?