我需要编写一个Perl脚本,在XML标签的句子开头用法语文本查找时间和位置实体。例如<temps> En été </temps>
(“夏天”)。
我在CSV文件中列出了位置名称,并在文本文件中列出了时刻列表(冬季,夏季,周一,周二等)。我读了两个数组@topo
和@tabplace
中的列表,原始文件每行一个单元格。
我想通过搜索以 En ,à, le 等开头的句子来检测实体(in,at等)结果存储在@entites
中。然后我需要分隔时间实体并放置实体:地点实体将存储在@places
中,时间实体将存储在@times
中。
我的问题是如何找到@entites
的任何条目,然后是@topo
的任何条目以及@times
我在想这样的事情,但我错过了一些步骤:
foreach my $celtime ( @entite ) {
@times = ( grep(/\b@entites.@tabtime/)
}
您的信息是完整的项目代码:
my @phrases = ();
my @topo = ();
my @entite = ();
my @tabplace = ();
my @tabtime = ();
my $fichiertexte;
my $celplace;
my $fichiertemps = 'entitemps.txt';
my $fichiertopo = 'toponymes.csv';
my $lignedic;
my $lignetemps;
print "Quel fichier voulez-vous segmentez ?\n";
$fichierstexte = <STDIN>;
chomp( $fichiertexte );
open( TEXT, ">>:encoding(utf8)", $fichiertexte )
or die( "Impossible d'ouvrir le fichier : ", $!, "\n" );
my @phrases = split( /\./, $lignetexte ); # Chaque phrase sur une ligne
while ( $lignetexte = <FICH> ) {
chomp( $lignetexte );
push( @phrases, $lignetexte );
}
close( TEXT );
open( TEMPS, ">>:encoding(utf8)", $fichiertemps )
or die( "Impossible d'ouvrir le fichier : ", $!, "\n" );
while ( $lignetemps = <FICH> ) {
chomp( $lignetemps );
push( @tabtime, $lignetemps ); # @tabtime = tableau des noms de temps
}
close( TEMPS );
open( DICO, "<:encoding(utf8)", $fichiertopo )
or die( "Impossible d'ouvrir le fichier : ", $!, "\n" );
while ( $lignedic = <FICH> ) {
chomp( $lignedic );
push( @topo, $lignedic ); # @topo = tableau des noms de lieu
}
close( DICO );
foreach my $cellule ( @phrases ) {
if ( grep( /\b(En|En|A|À|Au|Le|Ce|Du|Au).+/, $cellule ) ) { # Si la cellule commence par l'expression régulière
push( @entite, $cellule );
}
}
foreach my $celplace ( @entite ) {
#$cellieu = $cellieu.@dico
@places = ( grep( /\b$cellieu/ . @topo ); #places = tableau des entités de lieu
}
foreach my $celtime ( @entite ) {
@times = ( grep( /\b@entite.@tabtime/ ) ); #times = tableau des entité de temps
}
foreach my $entitetemps ( @times ) {
$entitelieu = "<temps>.$entitetemps.</temps>";
}
foreach my $entitelieu ( @places ) {
$entitelieu = "<lieu>.$entitetemps.</lieu>";
close( TEXT );
答案 0 :(得分:1)
我怀疑只是在一个数组中找到任何东西,然后在另一个数组中找到任何东西就足够了。语言通常表现不佳,通常需要更多的工作来匹配真实的短语
但是,我可以直接回答您的问题。这只是将正则表达式模式构建为字符串然后编译它的问题
我使用了地点A
,B
和C
,以及时刻X
,Y
和Z
。同
sprintf
和join
我构建了一个表示单词边界的正则表达式,然后是第一个数组中的任何一个,然后是一些空格,然后是第二个数组中的任何一个,以及另一个单词边界
我希望这会有所帮助
use strict;
use warnings 'all';
use feature 'say';
chomp( my @data = <DATA> );
my @topo = qw/ A B C /;
my @times = qw/ X Y Z /;
my $re = sprintf '\b(%s)\s+(%s)\b',
join( '|', @topo ),
join( '|', @times );
say "Regex: $re\n"; # Display the regex we've built
$re = qr/$re/i; # Compile the regex with case-independence
say 'All Data';
say for @data;
say '---';
say 'Matching Data';
say for grep /$re/, @data;
__DATA__
R P G X
E U Q B
K B V X
R J Q X
B Y H V
R L E D
A C Y T
G B Z O
P B Z X
R C X J
Y P N I
U L E O
M C Z V
I R T X
Regex: \b(A|B|C)\s+(X|Y|Z)\b
All Data
R P G X
E U Q B
K B V X
R J Q X
B Y H V
R L E D
A C Y T
G B Z O
P B Z X
R C X J
Y P N I
U L E O
M C Z V
I R T X
---
Matching Data
B Y H V
A C Y T
G B Z O
P B Z X
R C X J
M C Z V