正则表达式检测列表中的专有名词
Regex to detect proper nouns in a list
我有一个程序可以显示文本(标记化文本)中单词的频率列表,但我想要
第一:检测文本的专有名词并将它们附加到另一个列表中(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)
如果我的代码还有其他问题,请告诉我。
至于正则表达式部分,您的模式是 "a bit off"。大多数情况下,您会错过 字符 class、[abc]
的概念,例如匹配 class 中定义的集合中的单个字符的模式。
用于检测带有撇号并由连字符分隔的单词的正则表达式:
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 次或 0 次出现的 1+ 个单词字符,后跟 '
或 ’
\w+
- 1 个或多个单词字符
(?:-(?:\w+['’])?\w+)*
- 0 次或多次重复
-(?:\w+['’])?
- 可选的非捕获组匹配 1 次或 0 次出现的 1+ 个单词字符,后跟 '
或 ’
\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
确保他们后面有一个单词边界。
我有一个程序可以显示文本(标记化文本)中单词的频率列表,但我想要 第一:检测文本的专有名词并将它们附加到另一个列表中(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)
如果我的代码还有其他问题,请告诉我。
至于正则表达式部分,您的模式是 "a bit off"。大多数情况下,您会错过 字符 class、[abc]
的概念,例如匹配 class 中定义的集合中的单个字符的模式。
用于检测带有撇号并由连字符分隔的单词的正则表达式:
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 次或 0 次出现的 1+ 个单词字符,后跟'
或’
\w+
- 1 个或多个单词字符(?:-(?:\w+['’])?\w+)*
- 0 次或多次重复-(?:\w+['’])?
- 可选的非捕获组匹配 1 次或 0 次出现的 1+ 个单词字符,后跟'
或’
\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
确保他们后面有一个单词边界。