Python 如何从文本中删除小写的句子片段?
我正在尝试使用常规表达式或简单的Perl oneliner从标准文本文件中删除小写句子片段 例如,这些标签通常被称为语音标签或归属标签——他说,她说,等等 此示例显示在使用手动删除之前和之后:Python 如何从文本中删除小写的句子片段?,python,regex,perl,awk,Python,Regex,Perl,Awk,我正在尝试使用常规表达式或简单的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:这不是问题;只是格式化而已。我会在可能的时候发布。我在正则表达式中没有看到任何原子组——只有两个捕获组和一个负前瞻。