我有一句话:
text = "Alun-alun/NNP Jombang/NNP tepatnya/RB Depan/IN SMP/NNP 2/CDP Jombang/NNP Besok/NNP pagi/NN :/: :/: :/: Minggu/NNP"
我想从标记/IN
中提取任何单词,直到带有/NNP
标记的最后一个单词。
到目前为止,代码可以提取Depan/IN SMP/NNP 2/CDP Jombang/NNP Besok/NNP pagi/NN :/: :/: :/: Minggu/NNP
。但是如果代码符合/:
或/IN
标记,我希望它停止。这是迄今为止的代码:
import re
def entityExtract(text):
# text = re.findall(r'([^\s/]*/IN\b[^/]*(?:/(?!IN\b)[^/]*)*/NNP\b)', text)
text = re.findall(r'([^\s/]*/IN\b[^/]*(?:/(?!IN\b)[^/]*)*/(?:NNP|CDP)\b)', text)
return text
text = "Alun-alun/NNP Jombang/NNP tepatnya/RB Depan/IN SMP/NNP 2/CDP Jombang/NNP Besok/NNP pagi/NN :/: :/: :/: Minggu/NNP"
extract = entityExtract(text)
print text
print extract
输出:
['Depan/IN SMP/NNP 2/CDP Jombang/NNP Besok/NNP pagi/NN :/: :/: :/: Minggu/NNP']
预期结果是:
['Depan/IN SMP/NNP 2/CDP Jombang/NNP Besok/NNP]
解决问题的最佳方法是什么?
答案 0 :(得分:2)
[^\s/]*/IN\b([^/]*/(?!IN\b|:\b)[^\s^/]*\b)*[^/]*/NNP\b
我对@DYZ感到困惑,关于你想要停止的地方,所以我的正则表达式基于你的输出。
我相信你想要提取字符串的'word/tag'
部分,word+tag
是强耦合的。
您希望在不包含标记的情况下停止标记的位置由此组(?!IN\b|:\b|NN\b)
检查正则表达式here
答案 1 :(得分:1)
我看了@bulbus和@ytomo在评论中显示的正则表达式的答案,其中包括:
[^\s/]*/IN\b[^/]*(?:/(?!IN\b|:\b)[^/]*\b)*/(?:NNP|CDP)\b
我的问题是,这个 - 以及其他提议 - 不遵循逻辑顺序来为手头的问题创建正则表达式。让我告诉你:
第一部分,在重复小组[^\s/]*/IN\b[^/]*
之前,我将简化为\w+/IN\b
[^ /] *'匹配超过你想要的。请看example 1。
你在这里用语言解决的是:
将其直接翻译为正则表达式,您将获得更易读的版本。 (JMHO)
\w+/IN\b(\s[^/]+/[^\s]+)
在IN-group(example 2)\w+/IN\b(\s[^/]+/[^\s]+)*
重复第二组(example 3)\w+/IN\b(\s[^:/]+/(?!IN|:)[^\s]+)*
忽略:/:和\ w + / IN组(example 4)\w+/IN\b(\s[^:/]+/(?!IN|:)[^\s]+)*\s\w+/(NNP|CDP)\b
确保您的上一组是NNP或CDP(example 5)如果我们在前面的答案的评论中将这个与@ytomo的提议结果进行比较,似乎没有太大的区别。然而,我甚至不愿回答的原因是,正则表达式应该是可读的并且根据某些逻辑。你的代码将在明天开始生产,并且 - 当你的代码中断时 - 有人必须在一段时间的压力下检查它。