Regex 使用Perl正则表达式在多行上查找和提取匹配项

Regex 使用Perl正则表达式在多行上查找和提取匹配项,regex,perl,Regex,Perl,我有一个包含数百个术语的文本文件,格式如下: [Term] id: id1 name: name1 xref: type1:aab xref: type2:cdc [Term] id: id2 name: name2 xref: type1:aba xref: type3:fee 我需要提取外部参照类型为1的所有术语,并将它们以相同格式写入新文件。我计划使用如下正则表达式: /\[Term\](.*)type1(.*)[^\[Term\]]/g 查找相

我有一个包含数百个术语的文本文件,格式如下:

[Term]  
id: id1  
name: name1  
xref: type1:aab  
xref: type2:cdc  

[Term]  
id: id2  
name: name2  
xref: type1:aba  
xref: type3:fee 
我需要提取外部参照类型为1的所有术语,并将它们以相同格式写入新文件。我计划使用如下正则表达式:

/\[Term\](.*)type1(.*)[^\[Term\]]/g
查找相应的术语,但我不知道如何在多行上搜索正则表达式。我应该将原始文本文件作为字符串读取,还是逐行读取? 非常感谢您的帮助。

试试这个正则表达式:

/(?s)\[Term\].*?xref: type1.*?(?=\[Term\])/g
此正则表达式有以下显著变化:

  • (?s)
    打开“点匹配换行”
  • *?
    是一个非贪婪表达式。使用
    *
    将消耗文件中最后一个
    [Term]
    的所有内容
  • 删除了围绕
    *?
  • 添加了轻微的细化以匹配外部参照,而不仅仅是在任何地方键入1
  • 删除了下列术语标记的不正确语法
  • 添加了一个前瞻,以匹配下一个
    [Term]
    标记,但不包括该标记

另一种方法是使用
$/
变量在空行中拆分块,对于每个块,使用换行符拆分块,然后为每行运行正则表达式。因此,当其中一个匹配打印并读取下一个块时。带有一个衬里的示例:

perl -ne '
    BEGIN { $/ = q|| }
    my @lines = split /\n/;  
    for my $line ( @lines ) {
        if ( $line =~ m/xref:\s*type1/ ) {     
            printf qq|%s|, $_;
            last;
        }
    }
' infile
假设输入文件如下:

[Term]
id: id1
name: name1
xref: type1:aab
xref: type2:cdc

[Term]
id: id2
name: name1
xref: type6:aba
xref: type3:fee

[Term]
id: id2
name: name1
xref: type1:aba
xref: type3:fee

[Term]
id: id2
name: name1
xref: type4:aba
xref: type3:fee

[Term]  
id: id2  
name: name1  
xref: type1:aba  
xref: type3:fee
它产生:

[Term]  
id: id1  
name: name1  
xref: type1:aab  
xref: type2:cdc  

[Term]  
id: id2  
name: name1  
xref: type1:aba  
xref: type3:fee 

[Term]  
id: id2  
name: name1  
xref: type1:aba  
xref: type3:fee

正如您所看到的,只打印其中有一行
xref:type1

我尝试了以下方法:while(){$string=;@matches=$string=~(s)[Term](.*)type1(.*)(=[Term])/g;}close(MYFILE);但是它还不起作用,在正则表达式中返回“Unmatched”;标记为:在所有方括号之前是否有反斜杠?(它们没有显示在您的注释中。在注释中用反勾环绕代码以显示为代码字体)感谢您对新正则表达式的解释。我尝试了
while(){/(?s)\[Term\].*xref:type1.*(?=\[Term\])/g和print;}关闭(MYFILE);
但仍然没有输出。我应该以字符串或行对行的形式读取文件吗?要使其工作,您必须以单个输入读取文件-以“字符串”的形式。您能显示您的输出吗?非常感谢,它对我有效!现在我只需尝试并理解代码。。。