【问题标题】:Align words to form bracketed string对齐单词以形成带括号的字符串
【发布时间】:2021-04-05 00:10:56
【问题描述】:

假设,我有以下带标点符号的括号字符串:

s = "(S (NP-SBJ (NP (NP (NNP Ambassador) (NNP Paul) (NNP Nitze) (POS 's)) (NN statement)) (PRN (-LRB- -LRB-) (NP (NP-TTL (NNP Notable) (CC &) (NNP Quotable)) (, ,) (NP-TMP (NNP Sept.) (CD 20))) (-RRB- -RRB-) (, ,) (`` ``)) (S (SBAR-ADV (IN If) (S (NP-SBJ (PRP you)) (VP (VBP have) (NP (NP (DT a) (CD million) (NNS people)) (VP (VBG working) (PP (IN for) (NP (PRP you)))))))) (, ,) (NP-SBJ (NP (DT every) (JJ bad) (NN thing)) (SBAR (WHNP-1 (WDT that)) (S (VP (VBZ has) (NP (NP (CD one) (NN chance)) (PP (IN in) (NP (DT a) (CD million))) (PP (IN of) (S-NOM (VP (VBG going) (ADVP-CLR (NN wrong)))))))))) (VP (MD will) (VP (VB go) (ADVP-CLR (JJ wrong)) (ADVP-TMP (ADVP (IN at) (JJS least)) (IN once) (NP-ADV (DT a) (NN year)))))) (, ,) ('' '')) (VP (VBZ is) (NP-PRD (NP (DT a) (ADJP (RB pretty) (JJ negative)) (NN way)) (PP (IN of) (S-NOM (VP (VBG looking) (PP-CLR (IN at) (NP (NNS things)))))))) (. .))"

还有,我需要删除的标点参考列表:

punctuation_words = ['.', ',', ':', '-LRB-', '-RRB-', '\'\'', '``', '--', ';',
                     '-', '?', '!', '...', '-LCB-', '-RCB-']
currency_tags_words = ['#', '$', 'C$', 'A$', 'US$']
filterwords = punctuation_words + currency_tags_words

我想得到如下输出:

out = "(S (NP-SBJ (NP (NP (NNP Ambassador) (NNP Paul) (NNP Nitze) (POS 's)) (NN statement)) (PRN (NP (NP-TTL (NNP Notable) (CC &) (NNP Quotable)) (NP-TMP (NNP Sept.) (CD 20)))) (S (SBAR-ADV (IN If) (S (NP-SBJ (PRP you)) (VP (VBP have) (NP (NP (DT a) (CD million) (NNS people)) (VP (VBG working) (PP (IN for) (NP (PRP you)))))))) (NP-SBJ (NP (DT every) (JJ bad) (NN thing)) (SBAR (WHNP-1 (WDT that)) (S (VP (VBZ has) (NP (NP (CD one) (NN chance)) (PP (IN in) (NP (DT a) (CD million))) (PP (IN of) (S-NOM (VP (VBG going) (ADVP-CLR (NN wrong)))))))))) (VP (MD will) (VP (VB go) (ADVP-CLR (JJ wrong)) (ADVP-TMP (ADVP (IN at) (JJS least)) (IN once) (NP-ADV (DT a) (NN year))))))) (VP (VBZ is) (NP-PRD (NP (DT a) (ADJP (RB pretty) (JJ negative)) (NN way)) (PP (IN of) (S-NOM (VP (VBG looking) (PP-CLR (IN at) (NP (NNS things)))))))))"

到目前为止,这是我尝试过的:

import nltk

t = nltk.Tree.fromstring(s)
sent = " ".join(item[0] for item in t.pos())
sent_without_punct = " ".join([item for item in sent.split() if item not in filterwords])
print(sent_without_punct)
# "Ambassador Paul Nitze 's statement Notable & Quotable Sept. 20 If you have a million people working for you every bad thing that has one chance in a million of going wrong will go wrong at least once a year is a pretty negative way of looking at things"

这给了我没有标点符号的正确输出。但我很难将其合并回来以获取类似于out 的括号字符串。

编辑: POS 标签在这里不相关。因此,如果有帮助,我们可以将其替换为开始符号“S”,如下所示:

"(S (S (S (S (S Ambassador) (S Paul) (S Nitze) (S 's)) (S statement)) (S (S -LRB-) (S (S (S Notable) (S &) (S Quotable)) (S ,) .... "

【问题讨论】:

    标签: python regex string nltk


    【解决方案1】:

    您想删除像(A - A) 这样的模式,其中( 旁边的文本及其匹配的) 是相同的并且来自您的过滤字符串。

    你可以使用

    import re
    punctuation_words = ['.', ',', ':', '-LRB-', '-RRB-', '\'\'', '``', '--', ';',
                         '-', '?', '!', '...', '-LCB-', '-RCB-']
    currency_tags_words = ['#', '$', 'C$', 'A$', 'US$']
    filterwords = punctuation_words + currency_tags_words
    filter_rx = "|".join(sorted(map(re.escape,filterwords), key=len, reverse=True))
    rx = r"\s*\(({0}) \1\)".format(filter_rx)
    text = "(S (NP-SBJ (NP (NP (NNP Ambassador) (NNP Paul) (NNP Nitze) (POS 's)) (NN statement)) (PRN (-LRB- -LRB-) (NP (NP-TTL (NNP Notable) (CC &) (NNP Quotable)) (, ,) (NP-TMP (NNP Sept.) (CD 20))) (-RRB- -RRB-) (, ,) (`` ``)) (S (SBAR-ADV (IN If) (S (NP-SBJ (PRP you)) (VP (VBP have) (NP (NP (DT a) (CD million) (NNS people)) (VP (VBG working) (PP (IN for) (NP (PRP you)))))))) (, ,) (NP-SBJ (NP (DT every) (JJ bad) (NN thing)) (SBAR (WHNP-1 (WDT that)) (S (VP (VBZ has) (NP (NP (CD one) (NN chance)) (PP (IN in) (NP (DT a) (CD million))) (PP (IN of) (S-NOM (VP (VBG going) (ADVP-CLR (NN wrong)))))))))) (VP (MD will) (VP (VB go) (ADVP-CLR (JJ wrong)) (ADVP-TMP (ADVP (IN at) (JJS least)) (IN once) (NP-ADV (DT a) (NN year)))))) (, ,) ('' '')) (VP (VBZ is) (NP-PRD (NP (DT a) (ADJP (RB pretty) (JJ negative)) (NN way)) (PP (IN of) (S-NOM (VP (VBG looking) (PP-CLR (IN at) (NP (NNS things)))))))) (. .))"
    print( re.sub(rx, "", text) )
    

    请参阅Python demoregex demo

    正则表达式是\s*\(<PATTERN> \1\) 类型,并且匹配

    • \s* - 零个或多个空格
    • \( - 一个 ( 字符
    • (\-LRB\-|\-RRB\-|\-LCB\-|\-RCB\-|\.\.\.|\-\-|US\$|C\$|A\$|\.|''|``|\-|\?|\#|\$|,|:|;|!) - 过滤器之一
    • - 空格
    • \1 - 组 1 反向引用匹配与组 1 中捕获的相同文本
    • \) - 一个 ) 字符。

    【讨论】:

    • 感谢您的回答。但是,"(PP (ADVP (RB Yet)) (IN on) (NP (NP (NNS matters)) (ADJP (JJ close) (PP (TO to) (INTJ (UH er)) (NP (NN home))))) (: ...))" 失败了。就像我提到的,我想删除包含"..." 的括号。它前面可能有也可能没有"..."
    • @nikinlpds 如果第二个A 不需要与第一个相同,请使用rx = r"\s*\(({0}) {0}\)".format(filter_rx)。见this Python demo
    • 得到一个值错误,因为某些括号具有形状(S(S 字)),某些括号只有一个元素。
    • 我认为应该检查第二个元素是否在过滤词中,然后将括号完全去掉。
    • 我明白了,试试rx = r"\s*\([^\s()]+ (?:{0})\)".format(filter_rx),我在之前的评论中修改了 Python 演示链接中的代码。
    猜你喜欢
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    • 2017-04-03
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    相关资源
    最近更新 更多