Regex 如何使用Perl验证包含平衡文本的数据?

Regex 如何使用Perl验证包含平衡文本的数据?,regex,perl,Regex,Perl,我有一个文本文件,里面有独特的句型。独特的模式是: NAME [ e_NAME ] 名称[e_名称] 简单规则:如果括号内出现“e_u”,则“名称”必须紧跟在“e_u”之后 当字符串复杂时,问题就出现了。我将展示可能难以分析的终点情况: 与规则不匹配的行: (1) NAME1[blabla+NAME2[blabla+e_BAD2]+e_NAME1] (2) NAME1[blabla] + NAME2[e_BAD2] (3) NAME1[NAME2[blabla+e_BAD2]] + NAME3[

我有一个文本文件,里面有独特的句型。独特的模式是:

NAME [ e_NAME ] 名称[e_名称] 简单规则:如果括号内出现“e_u”,则“名称”必须紧跟在“e_u”之后

当字符串复杂时,问题就出现了。我将展示可能难以分析的终点情况:

与规则不匹配的行:

(1) NAME1[blabla+NAME2[blabla+e_BAD2]+e_NAME1] (2) NAME1[blabla] + NAME2[e_BAD2] (3) NAME1[NAME2[blabla+e_BAD2]] + NAME3[e_BAD3] (4) NAME1[e_NAME1BAD1] -> means it has to be only NAME1 (1) FOO1[blabla + 1] (2) [blalbla] + bla (3) bla + blabla (4) FOO1[ccc + ddd + FOO2[e_FOO2]] = 123 (5) FOO1[cc + FOO2[ dd ] ] + FOO3[e_FOO3] (1) 名称1[blabla+NAME2[blabla+e_-BAD2]+e_-NAME1] (2) 名称1[blabla]+NAME2[e_BAD2] (3) NAME1[NAME2[blabla+e_BAD2]]+NAME3[e_BAD3] (4) NAME1[e_NAME1BAD1]->表示它只能是NAME1 符合规则的行:

(1) NAME1[blabla+NAME2[blabla+e_BAD2]+e_NAME1] (2) NAME1[blabla] + NAME2[e_BAD2] (3) NAME1[NAME2[blabla+e_BAD2]] + NAME3[e_BAD3] (4) NAME1[e_NAME1BAD1] -> means it has to be only NAME1 (1) FOO1[blabla + 1] (2) [blalbla] + bla (3) bla + blabla (4) FOO1[ccc + ddd + FOO2[e_FOO2]] = 123 (5) FOO1[cc + FOO2[ dd ] ] + FOO3[e_FOO3] (1) FOO1[blabla+1] (2) [blalbla]+bla (3) 布拉+布拉 (4) FOO1[ccc+ddd+FOO2[e_FOO2]]=123 (5) FOO1[cc+FOO2[dd]]+FOO3[e_FOO3]
但我没能抓住这个终点…

也许你在寻找类似的东西:

 if ($string =~ /(\w+)\[e\\_(\w+)/ &&  $1 eq $2) {
     print "Pattern '$1' contained in string '$string'\n";
 }

根据你第一个问题的公认答案,我得出了以下结论:

use strict;
use warnings;

while (<DATA>) {
   my $l = $_;
   while (s/(\w+)\[([^\[\]]*)\]//) {
      my ($n, $chk) = ($1, $2);
      unless ($chk =~ /\be_$n\b/) {
         warn "Bad line: $l";
         last;
      }
   }
}

在澄清要求后编辑

或者可能有用。我最初用前者发布了一个答案,但不太喜欢。下面的示例使用了
Regexp::Common
,看起来相当简单

use strict;
use warnings;
use Regexp::Common;

my $PRE   = '[^[]*?';
my $VAR   = '\w+';
my $BRACK = $RE{balanced}{-parens=>'[]'};
my $POST  = '.*';

while (<DATA>){
    my ($bad, $full);

    # Brackets, if any, must balance
    $bad = 1 unless s/\[/[/g == s/\]/]/g;

    $full = $_;
    until ($bad){
        # Find some bracketed text and store all components.
        my ($pre, $var, $brack, $post) =
            $full =~ /^($PRE)($VAR)($BRACK)($POST)$/;
        last unless defined $brack;

        # Create a copy of the bracketed text, removing both the outer
        # brackets and all instances of inner-bracketed text.
        chop (my $clean = substr $brack, 1);
        $clean =~ s/$BRACK/ /g;

        # If e_FOO exists, FOO must equal $var.
        $bad = 1 if $clean =~ /e_(\w+)/ and $1 ne $var;

        # Remove the part of $full we've already checked.
        substr($full, 0, length($pre) + length($var) + 1, '');
    }

    print if $bad;
}

# Your test data, with some trailing comments.    
__DATA__
NAME1[blabla+NAME2[blabla+e_BAD2]+e_NAME1]               NOT OK 1
NAME1[blabla] + NAME2[e_BAD2]                            NOT OK 2
NAME1[NAME2[blabla+e_BAD2]] + NAME3[e_BAD3]              NOT OK 3
NAME1[e_NAME1BAD1]                                       NOT OK 4
FOO1[blabla + 1]                                         OK 1
[blalbla] + bla                                          OK 2
bla + blabla                                             OK 3
FOO1[ccc + ddd + FOO2[e_FOO2]] = 123                     OK 4
FOO1[cc + FOO2[ dd ] ] + FOO3[e_FOO3]                    OK 5
使用严格;
使用警告;
使用Regexp::Common;
我的$PRE='[^[]*?';
我的$VAR='\w+';
my$BRACK=$RE{balanced}{-parens=>'[]'};
我的$POST='.*';
而(){
我的($坏,$满);
#支架(如有)必须保持平衡
$bad=1,除非s/\[/[/g==s/\]/]/g;
$full=$\;
直到($bad){
#查找一些括号内的文本并存储所有组件。
我的($pre,$var,$brack,$post)=
$full=~/^($PRE)($VAR)($BRAK)($POST)$/;
最后,除非定义为$BRAK;
#创建括号内文本的副本,删除两个外部文本
#括号和内括号文本的所有实例。
印章(my$clean=substr$brack,1);
$clean=~s/$BRACK//g;
#如果e_FOO存在,FOO必须等于$var。
如果$clean=~/e_(\w+)/和$1 ne$var,则$bad=1;
#删除我们已经检查过的$full部分。
substr($full,0,长度($pre)+长度($var)+1,”);
}
如果$bad,则打印;
}
#您的测试数据,带有一些后续注释。
__资料__
名称1[blabla+NAME2[blabla+e_-BAD2]+e_-NAME1]不正常1
NAME1[blabla]+NAME2[e_BAD2]不正常2
NAME1[NAME2[blabla+e_BAD2]]+NAME3[e_BAD3]不正常3
名称1[e_name 1bad1]不正常4
FOO1[blabla+1]正常1
[blalbla]+blaok 2
布拉布拉+布拉布拉OK 3
FOO1[ccc+ddd+FOO2[e_FOO2]]=123正常4
FOO1[cc+FOO2[dd]]+FOO3[e_FOO3]正常5

CPAN很棒。

你的帖子毫无意义。我也不知道你的问题是什么。如果你已经问了这个问题,为什么不编辑这个问题,这会让它回到顶部,让问题变得更清晰、更有用?不要发布重复的帖子。你想在这里实际做什么?你只是想验证每一行吗包含特定的模式?首字母
NAME1
是指实际字符
NAME1
,还是一个表示任意字符串的变量?是的,我指的是规则的作用:)非常感谢你简洁的回答。我将把你的答案传过去,理解你写的每一行。你注意到我的回答了吗问题编辑?你的回答可能很有帮助,但需要一些我觉得很难分析的小变化。如果你能填补这个空白,我将非常感谢!)