2010-03-13 79 views
2

我打算使用常规表达式或简单的Perl oneliner从标准文本文件中删除小写句子片段。如何从文本中删除小写的句子片段?

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

这个例子显示了之前和使用手动删除后:

  1. 原文:

“啊,那是完全正确的!”阿辽沙惊呼道。

“噢,请不要玩傻瓜!有些白痴进来了,你把我们 羞愧!”在窗边哭泣的女孩,突然转向她的父亲 蔑视和轻蔑的空气。

“等一下,瓦尔瓦拉!”她的父亲哭着说道,但是很认真地看着他们。 “这是她的性格,”他说, 再次解决阿辽沙。

“你去哪儿了?”他问他。 “我想,”他说,“我忘记了一些东西......我的手帕,我想 ....好吧,即使我没有忘记任何东西,让我留一点 。”

他坐下了。父亲站在他身上。 “你也坐下,”他说。


  • 所有小写句子手动移除片段:
  • “啊,这是完全正确的”

    “噢,请不要玩傻瓜!有些白痴进来了,你把我们 羞愧!”

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

    “你去哪儿了?”

    “我想,”“我忘记了一些东西......我的手帕,我想 ....好吧,即使我没有忘记任何东西,让我留一点 。”

    他坐下了。父亲站在他身上。

    “你坐下了,”


    我变直引号“,以平衡和尝试:” [。](...)+

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

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

    干杯,

    亚伦

    +0

    如果不是“父亲站在他身上”,你会做什么?这句话是“父亲站在吉姆身上。”? – Robusto 2010-03-13 20:53:13

    +5

    我认为你需要给出一个更清晰的'小写句子片段'的定义。 特别是,为什么“惊叹阿辽沙”。一个小写的句子片段,但“父亲站在他身上。”不是? – Dancrumb 2010-03-13 21:06:14

    +0

    我认为“小写的句子片段”,他的意思是“信号短语”http://nutsandbolts.washcoll.edu/quoting.html#signal – 2010-03-14 21:47:49

    回答

    3

    下面是一个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 
    
    0

    Text::Balanced模块是你仿佛是,如果以后你打算使用Perl。下面应该能够提取你的例子中所有引用的语音(不漂亮,但完成工作)。

    它也适用于丹尼斯的测试案例。

    下面的代码的优点在于,报价是由段分组,其可以是或可以不是用于以后的分析

    有用脚本

    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}}; 
    

    __DATA__

    “啊,那是完全正确的!”阿辽沙惊呼道。 “

    ”哦,不要玩傻瓜! 有些白痴进来了,你把我们给 惭愧!“在窗边哭泣的女孩, 突然转向她的父亲与 轻蔑和轻蔑的空气。

    “等一下,瓦尔瓦拉!”哭泣她的父亲 ,说得很透露,但 非常赞赏地看着他们。 “这是她的性格,”他说, 再次解决阿辽沙。

    “你去哪儿了?”他问他。

    “我认为,”他说,“我忘了 东西......我的手帕,我觉得 ....好吧,即使我还没有 忘记任何东西,让我留一个 小“。

    他坐下了。父亲站在他身上。 “你也坐下,”他说。

    他说:“它并不总是奏效。”

    “其次,”我说,“ 三个引用短语失败......”他完成了 我的想法,“有两个没有引号的。

    我回答说:“没错。”沮丧。

    输出

    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." 
    
    +0

    'perl script.pl textfile'没有输出。 – 2010-03-14 00:48:37

    +0

    @丹尼斯:那是因为你需要以现在写的方式运行脚本作为'perl script.pl“文本”'。 – Zaid 2010-03-14 04:27:59

    +0

    然后几个OP的例子不起作用。 – 2010-03-14 04:43:13

    0

    我不完全相信你可以使用正则表达式的下面,您使用的,如果你使用的是支持原子团东西编辑器(如EditorPad专业版)主编做搜索和替换:

    搜索

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

    \1 
    

    这里替换为正则表达式一点解释:

    第一捕获组为报价和线开始以大写字母字符之间。第二个捕获组适用于在引用之后但在另一个引用之前的任何字符。

    +0

    我没有看到该正则表达式中的任何原子组 - 只有两个捕获组和负向前瞻。 – 2010-03-15 13:51:20

    0

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

    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. 
    
    0

    如果我明白你是什么后...每次路过通过这样的正则表达式应该工作...

    你可以使用perl调试器来玩弄这个。在linux/mac的命令行中跳入perl调试器,只有perl -de 42。 (其中“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); 
    } 
    

    注:对不起,我不得不编辑 - 没有看到你想要的行没有任何引号...

    是的,正则表达式和Perl是惊人的。它应该是100%准确的并获得所有实例,除非段落中的报价延伸