Perl 发现很难修复此问题。请通过检查我编辑的代码进行指导

Perl 发现很难修复此问题。请通过检查我编辑的代码进行指导,perl,Perl,我想检索文本文件计数中存在的函数(仅定义函数,而不是调用函数)的数量 下面是文本文件{function.txt} #include<main.h> #include<mncl.h> int reg23; int refid23; int64 AccounntBalance(char *reg12,char *refid,char **id){ //dis is function1 ref(); if(id>100) { do(&ref); }

我想检索文本文件计数中存在的函数(仅定义函数,而不是调用函数)的数量

下面是文本文件{function.txt}

#include<main.h>
#include<mncl.h>
int reg23;
int refid23;
int64 AccounntBalance(char *reg12,char *refid,char **id){  //dis is function1
ref();
if(id>100)
  {
  do(&ref);
  }
}                                                        //dis is end of fucntion1
void AccountRetrivalForm(char **regid,char **balance,char **id)   //dis is function2
   {
   doref(); 
   int register;
   if(refid!=null)
    {
   dolog();
     }
   }                                                     //dis is end of function2
现在,按照我的逻辑,程序是:

 #!C:/strawberry/perl
 use strict; 
 use warnings; 
 my $filename = 'function_perl.txt';
 my $function_count = 0;
 open(FILENAME,$filename);
 my @arr = join("\n",<FILENAME>);
foreach  my $string(@arr)
  {
 if($string =~/(?:int64|void|boolean)\s?(.*?)\(.*?\)\s*\{/)
     {
 print "HAI";
 $function_count++;
 print '$function_count';
  }
  }

这里的函数\u count是1。它在第二次匹配时从不递增。请用相同的代码帮助我…我尝试了这么久。我发现很难解决这个问题。

您的正则表达式格式不正确

^([int64/void/boolean)]/(.*)/\(/\{//\n
你的意思可能是:

/^(int64|void|boolean)\s+(\w+)\s*\(.*?\)\s*\{/

也就是说,int64、void或boolean、一些空格、标识符、可选空格、左括号、一些内容、右括号、一些可选空格(可能是换行符)和左大括号。

您的正则表达式格式不正确

^([int64/void/boolean)]/(.*)/\(/\{//\n
你的意思可能是:

/^(int64|void|boolean)\s+(\w+)\s*\(.*?\)\s*\{/

也就是说,int64、void或boolean、一些空格、标识符、可选空格、左括号、一些内容、右括号、一些可选空格(可能是换行符)和左大括号中的一个。

我想说的是,您浏览文件的方式是不寻常的。通常你会使用类似

open my $handle, '<', $filename;
while (<$handle>) {
    if (/^(void|boolean|int64).../) {
        do something;
    }
}
close $handle;
如果您试图在串联中使用一些未分配的变量,例如,和其他内容,则会发出警告。strict包强制您使用my关键字声明变量。这听起来有点麻烦,但它也可以防止您遇到问题,因为您刚刚输入了一个变量。使用strict时,Perl解释器将警告您有未声明的变量。autodie杂注检查系统调用(如open)是否失败

您使用的regexp是错误的。您必须知道Perl中的regexp是用斜杠括起来的,因此/\s+\w**/是一个有效的regexp。在这里,您在regexp中使用了一个斜杠,它会过早地关闭表达式。如果必须匹配文本中的反斜杠,则必须使用反斜杠或完全使用不同的分隔符对其进行转义


顺便说一句,您还有一个输入错误:@filecontent与@file\u content。这是一个完美的地方,使用严格;我会警告你的。

我想说,你浏览文件的方式是不寻常的。通常你会使用类似

open my $handle, '<', $filename;
while (<$handle>) {
    if (/^(void|boolean|int64).../) {
        do something;
    }
}
close $handle;
如果您试图在串联中使用一些未分配的变量,例如,和其他内容,则会发出警告。strict包强制您使用my关键字声明变量。这听起来有点麻烦,但它也可以防止您遇到问题,因为您刚刚输入了一个变量。使用strict时,Perl解释器将警告您有未声明的变量。autodie杂注检查系统调用(如open)是否失败

您使用的regexp是错误的。您必须知道Perl中的regexp是用斜杠括起来的,因此/\s+\w**/是一个有效的regexp。在这里,您在regexp中使用了一个斜杠,它会过早地关闭表达式。如果必须匹配文本中的反斜杠,则必须使用反斜杠或完全使用不同的分隔符对其进行转义


顺便说一句,您还有一个输入错误:@filecontent与@file\u content。这是一个完美的地方,使用严格;会警告你的。

也许这个例子会有帮助:

use strict;
use warnings;

my $n;

# Supply the input file name as a command-line argument.
# Perl will open the file and process it line by line.
# No need to hard-code the file name in the program, which
# means the script could be reused.
while (my $line = <>){
    # The regex is applied against $line.
    # It will return the items captured by parentheses.
    # The /x option causes Perl to ignore whitespace
    # in our definition of the regex -- for readability.
    my ($type, $func, $args) = $line =~ /^
        ( int64|void|boolean ) \s+
        ( \w+ )                \s*
        \( (.+?) \)
    /x;

    # Skip the line if our regex failed.
    next unless defined $type;

    # Keep track of N of functions, print output, whatever...
    $n ++;
    print $_, "\n" for '', $type, $func, $args;
}

print "\nN of functions = $n\n";

也许这个例子有助于:

use strict;
use warnings;

my $n;

# Supply the input file name as a command-line argument.
# Perl will open the file and process it line by line.
# No need to hard-code the file name in the program, which
# means the script could be reused.
while (my $line = <>){
    # The regex is applied against $line.
    # It will return the items captured by parentheses.
    # The /x option causes Perl to ignore whitespace
    # in our definition of the regex -- for readability.
    my ($type, $func, $args) = $line =~ /^
        ( int64|void|boolean ) \s+
        ( \w+ )                \s*
        \( (.+?) \)
    /x;

    # Skip the line if our regex failed.
    next unless defined $type;

    # Keep track of N of functions, print output, whatever...
    $n ++;
    print $_, "\n" for '', $type, $func, $args;
}

print "\nN of functions = $n\n";

这将实现以下目的:

#!/usr/bin/env perl
use strict;
use warnings;
use autodie qw(:all);

my $function_count = 0;
open my $input, '<', 'function.txt';
while (defined(my $line = <$input>)) {
    chomp($line);

    if (my ($func) = $line =~ /^(?:int64|void|boolean)\s?(.*?)\(/) {
        print qq{Found function "$func"\n};
        $function_count++;
    }
}
close $input;
print "$function_count\n";
考虑到函数调用,修改了答案:

#!/usr/bin/env perl
use strict;
use warnings;
use autodie qw(:all);

my $document;
{
    local $/ = undef;
    open my $input, '<', 'function.txt';
    $document = <$input>;
    chomp $document;
    close $input;
}

my $function_count = 0;
while (my ($func) = $document =~ /(?:int64|void|boolean)\s?(.*?)\(.*?\)\s*\{/gs)) {
    print qq{Found function "$func"\n};
    $function_count++;
}

print "$function_count\n";

这将实现以下目的:

#!/usr/bin/env perl
use strict;
use warnings;
use autodie qw(:all);

my $function_count = 0;
open my $input, '<', 'function.txt';
while (defined(my $line = <$input>)) {
    chomp($line);

    if (my ($func) = $line =~ /^(?:int64|void|boolean)\s?(.*?)\(/) {
        print qq{Found function "$func"\n};
        $function_count++;
    }
}
close $input;
print "$function_count\n";
考虑到函数调用,修改了答案:

#!/usr/bin/env perl
use strict;
use warnings;
use autodie qw(:all);

my $document;
{
    local $/ = undef;
    open my $input, '<', 'function.txt';
    $document = <$input>;
    chomp $document;
    close $input;
}

my $function_count = 0;
while (my ($func) = $document =~ /(?:int64|void|boolean)\s?(.*?)\(.*?\)\s*\{/gs)) {
    print qq{Found function "$func"\n};
    $function_count++;
}

print "$function_count\n";

正则表达式不是解析器。如果可以,最好使用解析器

一种简单的方法是依靠解析器:

处理需要源文件的名称和任何必要的编译器标志

sub usage { "Usage: $0 source-file [ cflags ]\n" }
翻译单元转储具有简单的格式:

@1 namespace_decl name: @2 srcp: :0 dcls: @3 @2 identifier_node strg: :: lngt: 2 @3 function_decl name: @4 mngl: @5 type: @6 srcp: prog.c:12 chan: @7 args: @8 link: extern @4 identifier_node strg: AccountRetrivalForm lngt: 19 假设一切顺利,我们将提取指定源文件中给出的函数定义

my $node = read_tu @tu;

sub isfunc {
  my($n) = @_;
  $n->{TYPE} eq "function_decl"
             &&
  index($n->{srcp}, "$src:") == 0;
}

sub nameof {
  my($n) = @_;
  return "<undefined>" unless exists $n->{name};
  $n->{name} =~ /^@/
    ? $node->{ $n->{name} }{strg}
    : $n->{name};
}

print "$_\n" for sort
                 map nameof($_),
                 grep isfunc($_),
                 values %$node;
运行示例:

$ ./getfuncs prog.cc AccounntBalance AccountRetrivalForm $ ./getfuncs prog.cc -I. AccounntBalance AccountRetrivalForm
正则表达式不是解析器。如果可以,最好使用解析器

一种简单的方法是依靠解析器:

处理需要源文件的名称和任何必要的编译器标志

sub usage { "Usage: $0 source-file [ cflags ]\n" }
翻译单元转储具有简单的格式:

@1 namespace_decl name: @2 srcp: :0 dcls: @3 @2 identifier_node strg: :: lngt: 2 @3 function_decl name: @4 mngl: @5 type: @6 srcp: prog.c:12 chan: @7 args: @8 link: extern @4 identifier_node strg: AccountRetrivalForm lngt: 19 假设一切顺利,我们将提取指定源文件中给出的函数定义

my $node = read_tu @tu;

sub isfunc {
  my($n) = @_;
  $n->{TYPE} eq "function_decl"
             &&
  index($n->{srcp}, "$src:") == 0;
}

sub nameof {
  my($n) = @_;
  return "<undefined>" unless exists $n->{name};
  $n->{name} =~ /^@/
    ? $node->{ $n->{name} }{strg}
    : $n->{name};
}

print "$_\n" for sort
                 map nameof($_),
                 grep isfunc($_),
                 values %$node;
运行示例:

$ ./getfuncs prog.cc AccounntBalance AccountRetrivalForm $ ./getfuncs prog.cc -I. AccounntBalance AccountRetrivalForm
你到底想匹配什么?以int64或void或boolean开头的函数?@gorillaPatch我正在尝试匹配所有可能以int64或void或boolean开头的函数这是仅有的三种可能我很好奇,dis来自哪种语言?你到底想匹配什么?以int64或void或boolean开头的函数?@gorillaPatch我正在尝试匹配所有可能以int64或void或boolean开头的函数。这是仅有的三种可能。我很好奇,dis来自哪种语言?很好!我喜欢直接命名regexp匹配项的方式。使代码更具可读性。我今天学到了一些东西。谢谢+1美元,很好

一我喜欢直接命名regexp匹配项的方式。使代码更具可读性。我今天学到了一些东西。谢谢+1。我认为不需要咀嚼这行代码,因为您没有匹配这行的结尾。非常正确,只是添加了咀嚼作为习惯。谢谢。但是上面的代码返回了函数调用的计数。。int64 AccountBalanceChar*reg12,char*refid,char**id;我认为不需要咀嚼这行代码,因为您没有匹配这行代码的末尾。非常正确,只是添加了咀嚼作为一种习惯。谢谢。但是上面的代码甚至返回了函数调用的计数。。int64 AccountBalanceChar*reg12,char*refid,char**id@daxim感谢您的编辑。为什么使用$handle格式的文件句柄而不是文件名更好?感谢您提供的提示daxim@daxim非常感谢。赫尔兹利钦潮湿@daxim感谢您的编辑。为什么使用$handle格式的文件句柄而不是文件名更好?感谢您提供的提示daxim@daxim非常感谢。赫尔兹利钦潮湿!这就是方法。不过,我认为你应该把CTAG放在前面。@Svante这是个好建议!我同意你的看法。这显然是他试图处理的一种基于c的语言,而且很容易用一些完全有效的函数声明破坏任何正则表达式。最好使用能理解语言的工具,这就是方法。不过,我认为你应该把CTAG放在前面。@Svante这是个好建议!我同意你的看法。这显然是他试图处理的一种基于c的语言,而且很容易用一些完全有效的函数声明破坏任何正则表达式。最好使用能理解语言的工具。