Python 如何从文本中删除小写的句子片段?

Python 如何从文本中删除小写的句子片段?,python,regex,perl,awk,Python,Regex,Perl,Awk,我正在尝试使用常规表达式或简单的Perl oneliner从标准文本文件中删除小写句子片段 例如,这些标签通常被称为语音标签或归属标签——他说,她说,等等 此示例显示在使用手动删除之前和之后: 原件: “啊,那完全是真的!”阿约沙喊道 “噢,别再装傻了!有个白痴进来了,你把我们关了 “真丢脸!”窗边的女孩喊道,突然转向她的父亲 带着轻蔑和轻蔑的神情 “等一下,瓦瓦拉!”她父亲喊道,专横地说,但是 非常赞许地看着他们。“这就是她的性格,”他说, 再次向阿约沙致辞 “你去哪儿了?”他问他 “我想,”

我正在尝试使用常规表达式或简单的Perl oneliner从标准文本文件中删除小写句子片段

例如,这些标签通常被称为语音标签或归属标签——他说,她说,等等

此示例显示在使用手动删除之前和之后:

  • 原件:
  • “啊,那完全是真的!”阿约沙喊道

    “噢,别再装傻了!有个白痴进来了,你把我们关了 “真丢脸!”窗边的女孩喊道,突然转向她的父亲 带着轻蔑和轻蔑的神情

    “等一下,瓦瓦拉!”她父亲喊道,专横地说,但是 非常赞许地看着他们。“这就是她的性格,”他说, 再次向阿约沙致辞

    “你去哪儿了?”他问他

    “我想,”他说,“我忘了什么……我的手帕,我忘了。” 想一想……好吧,即使我什么都没忘记,让我留下来 很少。”

    他坐了下来。父亲站在他身旁

    “你也坐下,”他说


  • 手动删除所有小写句子片段:
  • “啊,那完全是真的!”

    “噢,别再装傻了!有个白痴进来了,你把我们关了 可耻!”

    “等等,瓦瓦拉!”“那是她的性格,”

    “你去哪儿了?”

    “我想,”“我忘了什么……我的手帕,我 想一想……好吧,即使我什么都没忘记,让我留下来 很少。”

    他坐了下来。父亲站在他身旁

    “你也坐下,”


    我已经将“直接引用”改为“平衡引用”,并尝试:“(…)+[…]

    当然,这会删除一些片段,但会删除平衡引号中的一些文本以及以大写字母开头的文本。[^A-Z]在上述表达式中不起作用

    我意识到可能不可能达到100%的准确率,但任何有用的表达式、perl或python脚本都将受到高度赞赏

    干杯


    Aaron

    下面是一个Python代码片段,它应该可以:

     thetext="""triple quoted paste of your sample text"""
     y=thetext.split('\n')
     for line in y:
        m=re.findall('(".*?")',line)
        if m:
            print ' '.join(m)
        else:
            print line
    
    如果你想使用Perl,那么这个模块就是你想要的

    它也适用于Dennis的测试用例

    下面代码的优点是引号按段落分组,这可能对以后的分析有用,也可能不有用

    脚本

    use strict;
    use warnings;
    use Text::Balanced qw/extract_quotelike extract_multiple/;
    
    my %quotedSpeech;
    
    {
        local $/ = '';
        while (my $text = <DATA>) { # one paragraph at a time
    
            while (my $speech = extract_multiple(
                                $text,
                                [sub{extract_quotelike($_[0])},],
                                undef,
                                1))
            {   push @{$quotedSpeech{$.}}, $speech; }
        }
    }
    
    # Print total number of paragraphs in DATA filehandle
    
    print "Total paragraphs: ", (sort {$a <=> $b} keys %quotedSpeech)[-1];
    
    # Print quotes grouped by paragraph:
    
    foreach my $paraNumber (sort {$a <=> $b} keys %quotedSpeech) {
        print "\n\nPara ",$paraNumber;
        foreach my $speech (@{$quotedSpeech{$paraNumber}}) {
            print "\t",$speech,"\n";
        }
    }
    # How many quotes in paragraph 8?
    print "Number of quotes in Paragraph 8: ", scalar @{$quotedSpeech{8}};
    
    Total paragraphs: 10
    
    Para 1  "Ah, that's perfectly true!"
    
    
    Para 2  "Oh, do leave off playing the fool! Some idiot comes in, and you put us
    to shame!"
    
    
    Para 3  "Wait a little, Varvara!"
            "That's her character,"
    
    
    Para 4  "Where have you been?"
    
    
    Para 5  "I think,"
            "I've forgotten something... my handkerchief, I think.... Well, even if
    I've not forgotten anything, let me stay a little."
    
    
    Para 7  "You sit down, too,"
    
    
    Para 8  "It doesn't always work."
    
    
    Para 9  "Secondly,"
            "it fails for three quoted phrases..."
            "with two unquoted ones."
    
    
    Para 10 "That's right."
    

    我不完全确定您使用的是哪个编辑器,如果您使用的是支持原子分组的编辑器(例如EditorPad Pro),您可以使用下面的正则表达式进行搜索和替换:

    寻找

    (".+?"|^[A-Z].+\r\n)(.(?!"))* 
    Note: you should replace \r\n with \n or \r according to your line breaks
    
    取代

    \1
    
    下面是对正则表达式的一些解释:

    第一个捕获组用于引号和以大写字母开头的行之间的字符。第二个捕获组用于引号之后但另一个引号之前的任何字符


    这适用于问题中显示的所有情况:

    sed -n '/"/!{p;b}; s/\(.*\)"[^"]*/\1" /;s/\(.*"\)\([^"]*\)\(".*"\)/\1 \3/;p' textfile
    
    对于以下情况,它将失败:

    He said, "It doesn't always work."
    
    "Secondly," I said, "it fails for three quoted phrases..." He completed my thought, "with two unquoted ones."
    
    I replied, "That's right." dejectedly.
    

    如果我明白你的意思…通过这样的正则表达式传递每一行应该是有效的

    您可以使用perl调试器来处理这个问题。在linux/mac中,只需在命令行上使用
    perl-de 42
    即可进入perl调试器。(42只是一个有效的表达式-它可以是任何东西,但为什么不选择生命的意义?)

    无论如何

    open FILE, "<", "filename.txt" or die $!;
    while (my $line = <FILE>) {
       @fixed_text = $line =~ m{(?:(" .+? ")) | (?:\A .* [^"] .* \z)}xmsg;
      for my $new_line (@fixed_text) {
        print qq($new_line );
      }
      print qq(\n);
    }
    

    打开文件,“如果不是“父亲阻止了他”,而是“父亲阻止了吉姆”,你会怎么做?我认为你需要对什么是“小写句子片段”给出一个更清晰的定义。尤其是,为什么“Alyosha惊叫道。”是小写的句子片段,但“父亲站在他旁边。”不是吗?我想“小写的句子片段”的意思是“信号短语”
    perl script.pl textfile
    不产生输出。@Dennis:那是因为你需要以
    perl script.pl“text”的形式运行脚本
    现在的编写方式。@Dennis:查看更新的代码,它也适用于失败的案例。您的新版本更好,但它在多短语输入的部分之间打印换行符(例如,以“Wait”和“secondary”开头的部分)。@Dennis:这不是问题;只是格式化而已。我会在可能的时候发布。我在正则表达式中没有看到任何原子组——只有两个捕获组和一个负前瞻。