Perl使用正则表达式比较具有多个分隔符的字段

Perl使用正则表达式比较具有多个分隔符的字段,perl,Perl,我正在学习Perl。 My data.txt文件包含: Lori:James Apple Jamie:Eric Orange 我下面的代码打印出第一行“Lori:James Apple” open(文件'data.txt'); while(){ 打印if/James/; } 但是如何修改正则表达式来搜索特定字段呢? 例如,我想使用2个分隔符“”和“:”,使每行包含3个字段,并检查第一行的第3个字段是否为Apple。这相当于awk-F'[:]'$3=“Lori””data.txt使用正则表达式

我正在学习Perl。 My data.txt文件包含:

Lori:James Apple
Jamie:Eric Orange
我下面的代码打印出第一行“Lori:James Apple”

open(文件'data.txt');
while(){
打印if/James/;
}
但是如何修改正则表达式来搜索特定字段呢?
例如,我想使用2个分隔符“”和“:”,使每行包含3个字段,并检查第一行的第3个字段是否为Apple。这相当于
awk-F'[:]'$3=“Lori””data.txt
使用正则表达式的一个简单方法是使用

这也使用正则表达式作为分割字符串的模式。字符类不是否定的,因为在这里它指定了分隔符本身,或者是
或者
\s
(每个分隔符可以是其中的一个,它们不一定都是相同的)


我现在想回答一个具体的问题,但我不清楚这个问题

它询问“检查第一行的第三个字段是否为Apple”,例如,可以通过

while (<$fh>) 
{
    if ( (/([^:\s]+)/g)[2] eq 'Apple' ) {
        # ....
    }
}
while()
{
如果(/([^:\s]+)/g)[2]等式'Apple'){
# ....
}
}
但现在还不清楚该怎么处理它。也许通过第三个字段得到第一个字段

我建议先获取一个数组,然后进行处理。可以编写一个正则表达式来直接识别和拾取字段,但这更为脆弱,正则表达式本身取决于字段的位置(和数量)

在这一点上,我们是在猜测游戏。如果您需要更多详细信息,请澄清


给定的
awk
代码将产生
Lori James Lori
,我不知道这是怎么回事。

使用正则表达式的一个简单方法是使用

这也使用正则表达式作为分割字符串的模式。字符类不是否定的,因为在这里它指定了分隔符本身,或者是
或者
\s
(每个分隔符可以是其中的一个,它们不一定都是相同的)


我现在想回答一个具体的问题,但我不清楚这个问题

它询问“检查第一行的第三个字段是否为Apple”,例如,可以通过

while (<$fh>) 
{
    if ( (/([^:\s]+)/g)[2] eq 'Apple' ) {
        # ....
    }
}
while()
{
如果(/([^:\s]+)/g)[2]等式'Apple'){
# ....
}
}
但现在还不清楚该怎么处理它。也许通过第三个字段得到第一个字段

我建议先获取一个数组,然后进行处理。可以编写一个正则表达式来直接识别和拾取字段,但这更为脆弱,正则表达式本身取决于字段的位置(和数量)

在这一点上,我们是在猜测游戏。如果您需要更多详细信息,请澄清


给定的
awk
代码将产生
Lori James Lori
,我不知道这是否合适。

简单的答案是-不要。正则表达式与模式匹配有关,而与上下文无关

您可以定义在分隔符和字段中构建的模式,但是。。。这不是适合这项工作的工具

答案是使用
split
,然后分别处理字段

open ( my $input, '<', 'data.txt' ) or die $!; 
while(<$input>){
    chomp;
    my @fields = split /[\s:]/;
    print if $fields[2] eq "Apple";
}
是错误的样式-它不检查是否成功,并且它还使用全局文件句柄名称。最好是:

open ( my $input, '<', 'data.txt' ) or die $!;

open(my$input),简单的答案是-不要。正则表达式是关于模式匹配,而不是上下文

您可以定义一个在定界符和字段中构建的模式,但是…它不是适合该作业的工具

答案是使用
split
,然后分别处理字段

open ( my $input, '<', 'data.txt' ) or die $!; 
while(<$input>){
    chomp;
    my @fields = split /[\s:]/;
    print if $fields[2] eq "Apple";
}
是错误的样式-它不检查是否成功,并且它还使用全局文件句柄名称。最好:

open ( my $input, '<', 'data.txt' ) or die $!;

open(my$input),“如何修改正则表达式”这个特定问题的答案可能类似于
/^([^::*[:]){2}James($|[:])/
@tripleee是的,但我看不出具体问题是什么(提供的示例相互冲突)(顺便说一句,那应该是
{1}
我想?或者
Apple
而不是
James
{1}
是毫无意义的;如果某件事没有重复,你根本不需要指定重复的次数(否则我们会说
/J{1}a{m})e{1}s{1}/
)。我跳过了前两个字段和下面的分隔符,这就是为什么它是两个重复。但是,是的,可能在第三个字段中查找
Apple
,或者以第二个字段为目标。@tripleee同意,在我的注释中是对您注释中实际代码的附加注释(只是想指出,它不符合现状,以防有人盲目复制)。当然,这是一种按字段解析的好方法。(顺便说一句,我不建议在开始研究时这样做。顺便说一句,老实说,我个人也不喜欢复杂生产代码中的那些。)我很乐意提供一个有趣的正则表达式作为附带的答案,但实际上我不知道确切的问题是什么。我知道没有一个,他们一般都在问如何做。@tripleee谢谢你的评论!见到你总是很高兴:)关于“如何修改正则表达式”的具体问题我想答案可能是
/^([^:::*[:]){2}James($|[:])/
@tripleee是的,但我不知道具体的问题是什么(提供的示例相互冲突)。我确实添加了另一个部分…但我觉得我在这一点上是在猜测。(顺便说一句,这需要
{1}
我认为?或者
苹果
而不是
詹姆斯
{1}
是毫无意义的;如果某件事没有重复,你就不需要指定重复的次数(或者我们可以说
/J{1}a{1}m{1}e{1}/
)。我跳过了前两个字段和下面的分隔符,这就是为什么它是两个重复。但是,是的,可能在第三个字段中查找
Apple
,或者以第二个字段为目标。@tr
open ( my $input, '<', 'data.txt' ) or die $!;