【问题标题】:Finding a string in a subroutine with perl PPI使用 perl PPI 在子例程中查找字符串
【发布时间】:2015-07-15 11:32:03
【问题描述】:

这个问题与How can I find all the methods that contain a specific string within a Perl codeset? 松散相关。

在解决这个问题时,Hakon 有用地建议我查看PPI

PPI 引起了我的兴趣,作为一项学习练习,我一直在尝试使用它来传递文件并在文件中查找包含特定字符串的方法。

PPI 大且功能丰富,我一直坚持在子例程中搜索的最佳方式。我对 PDOM 的理解和查找字符串的最佳方法都陷入了困境

到目前为止我有:

#The file to parse
open(my $fh, '<:encoding(UTF-8)', $filename)
    or die "Could not open file '$filename' $!";

#Read in the entire file (they're not that large).
my $src = do { local $/; <$fh> };

# Load a document
my $doc = PPI::Document->new( \$src );
my $subs_ref = $doc->find( sub { $_[1]->isa('PPI::Statement::Sub') });

#Test I actually have the subs print their names...
my @sub_names = map { $_->name } @$subs_ref;
warn "@sub_names";

# This is where I get stuck.  Do I now use PPI::Find?
my $result = $subs_ref->find( \&wanted ); #What does wanted contain?

#I can see I now have PDOM objects created for individual subroutines within file   
my $sub = $subs_ref->[0];
warn "name is " . $sub->name;
warn Dumper $sub;

使用上面我可以看到我已经解析了文件并且可以访问文件中每个子例程的 PDOM 对象。

PDOM 对象的示例如下所示:

$VAR1 = bless( {
                 'children' => [
                                 bless( {
                                          'content' => 'sub'
                                        }, 'PPI::Token::Word' ),
                                 bless( {
                                          'content' => ' '
                                        }, 'PPI::Token::Whitespace' ),
                                 bless( {
                                          'content' => 'Welcome'
                                        }, 'PPI::Token::Word' ),
                                 bless( {
                                          'content' => ' '
                                        }, 'PPI::Token::Whitespace' ),
                                 bless( {
                                          'finish' => bless( {
                                                               'content' => '}'
                                                             }, 'PPI::Token::Structure' ),
                                          'start' => bless( {
                                                              'content' => '{'
                                                            }, 'PPI::Token::Structure' ),
                                          'children' => [

我正在搜索可能包含在双引号或单引号中的字符串。例如:

bless( {
'separator' => '"',
'content' => '"signup/welcome_$user_type"'
}, 'PPI::Token::Quote::Double' ),

我的问题: 在 $subs_ref->[i] 中搜索“注册/欢迎”的最佳方法是什么?我是使用 PPI::Find(如果是,你能给我举个例子吗?)还是有更好的方法?

【问题讨论】:

    标签: perl


    【解决方案1】:

    您可以尝试遍历每个子例程的所有 PPI::Token::Quote::Double,例如:

    my @result = map {[ $_->name, $_->find( 'PPI::Token::Quote::Double' )] } @$subs_ref;
    
    for my $elem (@result) {
        say $elem->[0];
        my $found = 0;
        for my $node ( @{$elem->[1]} ) {
            my $str = $node->content;
            $found = 1 if $str =~ "signup/welcome";
        }
        say "-->" . ($found ? "found" : "not found");
    }
    

    【讨论】:

    • 嘿 Hakon,我开始看这个,但我觉得它不是最佳的,因为字符串可能是 Quote::Double、Quote::Single 或可能是我不知道的东西。然后我想也许find是方法,然后我停下来问:)
    • @mark 我不确定如何简化这一点,但无论如何这是一个好问题。很高兴了解 PPI 的这一功能 :)
    • PPI 似乎真的很有用,但我认为它需要一本简单操作的食谱。我会试着把一个放在一起分享。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    • 2015-12-31
    • 1970-01-01
    • 2011-07-13
    相关资源
    最近更新 更多