我有一个字符串:
123 + FOO1[ccc + e_FOO1 + ddd + FOO2[b_FOO2]] = 123
现在,我需要检查FOO1
是否与e_
一起显示。也就是说,不可能出现这样的情况:
123 + FOO1[ccc + e_FOK1 ...]
我的简单问题是如何告诉Perl捕获FOO1字样?
我想在2个字符之间进行搜索:" "
和"["
然后检查" e_"
之间的"[..]"
之后是否正确写入。
我如何能够回收?
答案 0 :(得分:2)
您需要为您的迷你语言编写解析器:请参阅Parse::RecDescent。 calculator demo将是一个很好的起点。
#!/usr/bin/perl
use strict;
use warnings;
my ($expr) = @ARGV;
my @tokens = split //, $expr;
my ($word, $inside) = (q{}, 0);
for my $token (@tokens) {
$token =~ /\A\w\z/ and do { $word .= $token; next };
if ( $inside ) {
if ( $word =~ /FOO1/ ) {
$word eq 'e_FOO1'
or die "No FOO1 w/o e_ prefix allowed!\n"
}
}
else {
$word !~ /FOO1/
or die "No FOO1 allowed!\n";
}
$token eq '[' and ++$inside;
$token eq ']' and --$inside;
$word = '';
}
C:\Temp> t.pl "123 + MOO1[ccc + e_FOO1 + ddd + FOO2[b_FOO2]] = 123"
C:\Temp> t.pl "123 + FOO1[ccc + e_FOO1 + ddd + FOO2[b_FOO2]] = 123" No FOO1 allowed!
C:\Temp> t.pl "123 + MOO1[ccc + FOO1 + ddd + FOO2[b_FOO2]] = 123" No FOO1 w/o e_ prefix allowed!
另请参阅常见问题解答Can I use Perl regular expressions to match balanced text?
答案 1 :(得分:1)
根据你的一些评论,我将假设你的问题是“在'['和']'括号之间,确保任何'e_'符号都是'e_FOO'而不是别的...
(编辑:好吧,看起来您需要“FOO”关键字也出现在方括号前面。我会相应地修改正则表达式。)
if ($line =~ /
([A-Z]+) # match a keyword in all caps, and save it for later
# (we can retrieve it with \1 or $1)
\[ # match the first [
[\]]* # some number of any character that isn't ]
e_ # a ha, here's our e_
\1 # and here's our keyword that we matched earlier
[\]]* # some more of any character that isn't ]
\] # here's our closing ]
/x)
{
say "Good data";
}
else
{
say "Bad data";
}
但是,请开始阅读perldoc perlre中的一些教程。
答案 2 :(得分:0)
如果你的情况比你描述的更复杂,那么这段代码就行不通了(例如,它没有做任何事情来确保你的左右括号相互平衡)。但是,代码确实说明了如何使用反向引用(请参阅下面的\1
),这可能会让您走上正确的轨道。
use strict;
use warnings;
while (<DATA>){
warn "Bad line: $_" unless / (\w+) \[ .* e_\1 .* \] /x;
}
__DATA__
123 + FOO1[ccc + e_FOO1 + ddd + FOO2[b_FOO2]] = 123
123 + FOO1[ccc + e_FOOx + ddd + FOO2[b_FOO2]] = 123
答案 3 :(得分:0)
因为您说“我需要确认FOO1是否遵循其括号内的”e_“字符串”,您只需要检查e_FOO1,对吗?不需要太复杂的正则表达式。
my $str="123 + FOO1[ccc + e_FOO1 + ddd + FOO2[b_FOO2]] = 123";
my $s = index($str,"[");
my $e = index($str,"]");
my $f = index($str,"e_FOO1");
if ( $f >=$s and $f <= $e ){
print "found \n";
}