Perl 如何使用计数器查找单词的位置?
我目前正在编写一个代码,将某些单词更改为莎士比亚的单词。我必须提取包含单词的句子并将它们打印到另一个文件中。我必须删除。从每个文件的开头开始 首先,我将文件与文本按空格分开,所以现在我有了单词。接下来,我通过一个散列重复这些单词。散列键和值来自以制表符分隔的文件,该文件的结构如下:OldEng/ModernEng(Perl 如何使用计数器查找单词的位置?,perl,Perl,我目前正在编写一个代码,将某些单词更改为莎士比亚的单词。我必须提取包含单词的句子并将它们打印到另一个文件中。我必须删除。从每个文件的开头开始 首先,我将文件与文本按空格分开,所以现在我有了单词。接下来,我通过一个散列重复这些单词。散列键和值来自以制表符分隔的文件,该文件的结构如下:OldEng/ModernEng(lc\u Shakespeare\u lexicon.txt)。现在,我正试图找出每一个现代英语单词的确切位置,把它改成莎士比亚的;然后找出有变化的单词的句子,并将它们打印到不同的文件
lc\u Shakespeare\u lexicon.txt
)。现在,我正试图找出每一个现代英语单词的确切位置,把它改成莎士比亚的;然后找出有变化的单词的句子,并将它们打印到不同的文件中。除最后一部分外,大部分代码都已完成。以下是我目前的代码:
#!/usr/bin/perl -w
use diagnostics;
use strict;
#Declare variables
my $counter=();
my %hash=();
my $conv1=();
my $conv2=();
my $ssph=();
my @text=();
my $key=();
my $value=();
my $conversion=();
my @rmv=();
my $splits=();
my $words=();
my @word=();
my $vals=();
my $existingdir='/home/nelly/Desktop';
my @file='Sentences.txt';
my $eng_words=();
my $results=();
my $storage=();
#Open file to tab delimited words
open (FILE,"<", "lc_shakespeare_lexicon.txt") or die "could not open lc_shakespeare_lexicon.txt\n";
#split words by tabs
while (<FILE>){
chomp($_);
($value, $key)= (split(/\t/), $_);
$hash{$value}=$key;
}
#open directory to Shakespearean files
my $dir="/home/nelly/Desktop/input";
opendir(DIR,$dir) or die "can't opendir Shakespeare_input.tar.gz";
#Use grep to get WSJ file and store into an array
my @array= grep {/WSJ/} readdir(DIR);
#store file in a scalar
foreach my $file(@array){
#open files inside of input
open (DATA,"<", "/home/nelly/Desktop/input/$file") or die "could not open $file\n";
#loop through each file
while (<DATA>){
@text=$_;
chomp(@text);
#Remove .START
@rmv=grep(!/.START/, @text);
foreach $splits(@rmv){
#split data into separate words
@word=(split(/ /, $splits));
#Loop through each word and replace with Shakespearean word that exists
$counter=0;
foreach $words(@word){
if (exists $hash{$words}){
$eng_words= $hash{$words};
$results=$counter;
print "$counter\n";
$counter++;
#create a new directory and store senteces with Shakespearean words in new file called "Sentences.txt"
mkdir $existingdir unless -d $existingdir;
open my $FILE, ">>", "$existingdir/@file", or die "Can't open $existingdir/conversion.txt'\n";
#print $FILE "@words\n";
close ($FILE);
}
}
}
}
}
close (FILE);
close (DIR);
#/usr/bin/perl-w
使用诊断;
严格使用;
#声明变量
我的$counter=();
我的%hash=();
我的$conv1=();
我的$conv2=();
我的$ssph=();
我的@text=();
我的$key=();
我的美元价值=();
我的$conversion=();
我的@rmv=();
我的$splits=();
我的$words=();
我的@word=();
我的$VAL=();
my$existingdir='/home/nelly/Desktop';
我的@file='classifications.txt';
我的$eng_words=();
我的$results=();
我的$storage=();
#打开文件到制表符分隔的单词
open(FILE),“自然语言处理很难做到正确,除非是在一些琐碎的情况下,例如,很难准确定义单词或句子的含义,而且当使用U+0027
”撇号表示单引号和撇号时,很难区分它们“字符”
没有任何示例数据,很难编写可靠的解决方案,但下面的程序应该相当接近
请注意以下几点
使用警告
优于shebang行上的-w
- 一个程序应该包含尽可能少的注释,只要它是可理解的。太多的注释只会使程序更大,更难掌握,而不添加任何新的信息。标识符的选择应该使代码主要是自文档化的
- 我认为
use diagnostics
是不必要的。大多数消息都是不言自明的,而且diagnostics
会产生大量不必要的输出
- 由于您要打开多个文件,因此使用autodie
更为简洁,这将避免显式测试每个打开
调用是否成功
openmyfh…
,而不是全局句柄,如openfh…
。首先,词法文件句柄在超出范围时会隐式关闭,这有助于通过使显式close
调用变得不必要来整理程序lc
对原始单词进行小写。如果找到翻译,则如果原始单词以大写字母开头,则使用ucfirst
对新词进行大写$content
的开头提取下一个句子。但是如果没有示例数据,这是我无法正确理解的事情之一,并且很可能存在问题,例如,以右引号或右括号结尾的句子使用严格;
使用警告;
使用自动模具;
my$lexicon='lc_shakespeare_lexicon.txt';
my$dir='/home/nelly/Desktop/input';
my$existing_dir='/home/nelly/Desktop';
我的$SECTURES='SECTURES.txt';
我的%lexicon=do{
打开我的($fh),“>”,“$existing_dir/$SECTURES”;
打印“@words\n”;
}
}
}
你能发布一些输入数据吗?在需要之前声明变量,你就失去了my
的一些好处。此外,所有这些赋值(除了my$existingdir='/home/nelly/Desktop';my@file='句子.txt';
)都是无用的。很可能你将要使用索引pos
和类似的东西-就像这样。我不知道你是否在这里正确设置了查找%hash
。尝试使用或查看它是如何填写的。句子是如何存储在文件中的?每行一句话?有几个问题需要解决在Perl代码中,尝试在顶部添加使用警告;
,然后解析警告消息。最好让使用警告
而不是-w
。此外,数据
是Perl的一个特殊文件句柄名称,因此您不应该对自己的文件使用它。当前的最佳做法是对文件句柄使用词法变量 (打开我的$in_fh,'谢谢你,这帮了大忙。我真的很感激你指出了我的弱点!!@Borodin我很难完全理解OP的意图。不过,听起来他们好像真的想重建句子结构。如果是这样的话,那么正则表达式解决方案似乎更合适,而不是按空格。s{(\w+)}{…}例如
。顺便说一句,干得不错。
use strict;
use warnings;
use autodie;
my $lexicon = 'lc_shakespeare_lexicon.txt';
my $dir = '/home/nelly/Desktop/input';
my $existing_dir = '/home/nelly/Desktop';
my $sentences = 'Sentences.txt';
my %lexicon = do {
open my ($fh), '<', $lexicon;
local $/;
reverse(<$fh> =~ /[^\t\n\r]+/g);
};
my @files = do {
opendir my ($dh), $dir;
grep /WSJ/, readdir $dh;
};
for my $file (@files) {
my $contents = do {
open my $fh, '<', "$dir/$file";
join '', grep { not /\A\.START/ } <$fh>;
};
# Change any CR or LF to a space, and reduce multiple spaces to single spaces
$contents =~ tr/\r\n/ /;
$contents =~ s/ {2,}/ /g;
# Find and process each sentence
while ( $contents =~ / \s* (.+?[.?!]) (?= \s+ [A-Z] | \s* \z ) /gx ) {
my $sentence = $1;
my @words = split ' ', $sentence;
my $changed;
for my $word (@words) {
my $eng_word = $lexicon{lc $word};
$eng_word = ucfirst $eng_word if $word =~ /\A[A-Z]/;
if ($eng_word) {
$word = $eng_word;
++$changed;
}
}
if ($changed) {
mkdir $existing_dir unless -d $existing_dir;
open my $out_fh, '>>', "$existing_dir/$sentences";
print "@words\n";
}
}
}