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

时间:2010-03-13 20:48:09

标签: python regex perl awk

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

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

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

  1. 原件:
  2. “啊,这是完全正确的!” Alyosha大声说道。

    “哦,不要玩傻瓜!有些白痴进来,你把我们放进去 羞愧!“窗边的女孩喊道,突然转向她的父亲 带着蔑视和轻蔑的气氛。

    “等一下,瓦尔瓦拉!”她的父亲大声说道,但是 非常赞赏地看着他们。 “这是她的性格,”他说, 再次对Alyosha说。

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

    “我想,”他说,“我忘记了什么......我的手帕,我 想想......好吧,即使我没有忘记任何事情,让我留下来 小“。

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

    “你也坐下来,”他说。


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

      “哦,不要玩傻瓜!有些白痴进来,你把我们放进去 羞耻!“

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

      “你去哪儿了?”

      “我想,”“我忘了什么......我的手帕,我 想想......好吧,即使我没有忘记任何事情,让我留下来 小“。

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

      “你也坐下来,”


      我改变了直接引用“以平衡并尝试:”(...)+ [。]

      当然,这会删除一些片段,但会删除平衡引号中的一些文本和以大写字母开头的文本。 [^ A-Z]在上面的表达中没有用。

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

      干杯,

      亚伦

5 个答案:

答案 0 :(得分: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

答案 1 :(得分: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__

     “啊,这是完全正确的!” Alyosha大声说道。

     

“哦,不要玩傻瓜!   有些白痴进来,你把我们带到了   惭愧!“窗边的女孩叫道,   突然转向她的父亲   轻蔑和轻蔑的气氛。

     

“等一下,瓦尔瓦拉!”她喊道   父亲,一言不发,但是   非常赞赏地看着他们。   “这是她的性格,”他说,   再次对Alyosha说。

     

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

     

“我想,”他说,“我已经忘记了   什么......我的手帕,我   想想......好吧,即使我没有   忘了什么,让我留下来   小“。

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

     

“你也坐下来,”他说。

     

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

     

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

     

我回答说,“那是对的。”沮丧。

<强>输出

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

答案 2 :(得分:0)

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

搜索

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

替换为

\1

以下是正则表达式的一些解释:

  

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

答案 3 :(得分: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.

答案 4 :(得分:0)

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

您可以使用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);
}

注意:抱歉,我必须编辑它 - 没有看到你想要的行没有任何引号......

是的,Regex和Perl很棒。它应该是100%准确并获得所有实例,除非引用扩展到段落