我有一个程序,可以显示文本(标记化文本)中单词的频率列表,但我想要 首先:检测文本的专有名词并将它们附加到另一个列表中(Cap_nouns) 第二:将字典中没有的名词附加到另一个列表中(错误),
稍后,我想为找到的这些错误创建一个频率列表,并为找到的专有名词创建另一个频率列表。
我检测专有名词的想法是找到以大写字母开头的项目并将它们附加到此列表中,但似乎此任务的正则表达式不起作用。
有人可以帮我吗?我的代码如下。
from collections import defaultdict
import re
import nltk
from nltk.tokenize import word_tokenize
with open('fr-text.txt') as f:
freq = word_tokenize(f.read())
with open ('Fr-dictionary_Upper_Low.txt') as fr:
dic = word_tokenize(fr.read())
#regular expression to detect words with apostrophes and separated by hyphens
pat=re.compile(r".,:;?!-'%|\b(\w'|w’)+\b|\w+(?:-\w+)+|\d+")
reg= list(filter(pat.match, freq))
#regular expression for words that start with a capital letter
patt=re.compile(r"\b^A-Z\b")
c_n= list(filter(patt.match, freq))
d=defaultdict(int)
#Empty list to append the items not found in the dictionary
errors=[ ]
Cnouns=[ ] #Empty list to append the items starting with a capital letter
for w in freq:
d[w]+=1
if w in reg:
continue
elif w in c_n:
Cnouns.append(w)
elif w not in dic:
errors.append(w)
for w in sorted(d, key=d.get):
print(w, d[w])
print(errors)
print(Cnouns)
如果我的代码还有其他问题,请告诉我。
最佳答案
至于正则表达式部分,您的模式“有点偏离”。大多数情况下,您会错过字符类的概念,[abc]
类似于匹配类中定义的集合中的单个字符的模式。
检测带有撇号并用连字符分隔的单词的正则表达式:
pat=re.compile(r"(?:\w+['’])?\w+(?:-(?:\w+['’])?\w+)*")
请参阅regex demo 。但是,它也会匹配常规数字或简单单词。为了避免匹配它们,您可以使用
pat=re.compile(r"(?:\w+['’])?\w+(?:-(?:\w+['’])?\w+)+|\w+['’]\w+")
参见this regex demo .
详细信息
(?:\w+[''])?
- 可选的非捕获组,匹配 1 个以上单词字符出现 1 次或 0 次,后跟'
或'
\w+
- 1 个或多个单词字符(?:-(?:\w+[''])?\w+)*
- 0 次或多次重复-(?:\w+[''])?
- 可选的非捕获组,匹配 1 个以上单词字符出现 1 次或 0 次,后跟'
或'
\w+
- 1 个或多个单词字符
接下来,reg = list(filter(pat.match, freq))
可能无法满足您的需要,如re.match
only matches at the start of the string 。您很可能想使用re.match
:
reg = list(filter(pat.search, freq))
^^^^^^
以大写字母开头的单词的正则表达式可以这样写
patt=re.compile(r"\b[A-Z][a-z]*\b")
c_n= list(filter(patt.search, freq))
\b
匹配单词边界,[A-Z]
匹配任何大写 ASCII 字母,[a-z]*
部分匹配 0或更多小写 ASCII 字母和 \b
确保它们后面有单词边界。
关于python - 正则表达式检测列表中的专有名词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55264009/