如何从Perl正则表达式匹配中获取多个内存? Pr> ReGEX搜索的目的是从C++头文件中确定所有模板类实例。类实例的格式如下: CMyClass<int> myClassInstance; CMyClass2< int, int > myClass2Instacen; CMyClass myClassInstance; CMyClass2< int, int >MyClass2安装程序;

如何从Perl正则表达式匹配中获取多个内存? Pr> ReGEX搜索的目的是从C++头文件中确定所有模板类实例。类实例的格式如下: CMyClass<int> myClassInstance; CMyClass2< int, int > myClass2Instacen; CMyClass myClassInstance; CMyClass2< int, int >MyClass2安装程序;,regex,perl,multiline,Regex,Perl,Multiline,通过将整个文件加载到字符串中执行搜索: open(FILE, $file); $string = join('',<FILE>); close(FILE); 打开(文件,$FILE); $string=join(“”,); 关闭(文件); 下面的正则表达式用于确定类实例,即使该类实例跨越字符串中的多行: $search_string = "\s*\w[^typename].*<(\s*\w\s*,?\n?)*)>\s*\w+.*"; $string =~ m/$sea

通过将整个文件加载到字符串中执行搜索:

open(FILE, $file);
$string = join('',<FILE>);
close(FILE);
打开(文件,$FILE);
$string=join(“”,);
关闭(文件);
下面的正则表达式用于确定类实例,即使该类实例跨越字符串中的多行:

$search_string = "\s*\w[^typename].*<(\s*\w\s*,?\n?)*)>\s*\w+.*";
$string =~ m/$search_string/; 
$search\u string=“\s*\w[^typename].\s*\w+.*”;
$string=~m/$search_string/;
问题是,即使文件中存在更多的类实例,搜索也只返回一次命中


使用这种方法是否可以从一个regex backreferences变量中获取所有命中数

您需要的是
\G
修饰符。它将在最后一个匹配后开始字符串的下一个匹配

以下是Perl文档中的文档(链接有问题,因此您必须复制和粘贴):

“%5cG”-在正则表达式%3f中


首先,如果您要清除文件,应该使用。然后你可以做:

my $contents = read_file $file;
读取文件出错时会发出咯咯声

其次,[^typename]不仅排除字符串“typename”,还排除包含这些字符的任何字符串。除此之外,我并不清楚您使用的模式是否会始终匹配您希望它匹配的内容,但我现在无法对此发表评论

最后,要逐个获取文件中的所有匹配项,请在循环中使用g修饰符:

my $source = '3 5 7';

while ( $source =~ /([0-9])/g ) {
    print "$1\n";
}
现在我已经有机会了解了您的模式,我仍然不确定如何使用[^typename],但下面是一个示例程序,它捕获了尖括号之间的部分(因为这似乎是您在上面捕获的唯一内容):

使用严格;
使用警告;
使用File::Slurp;
我的$pattern=qr{
^
\w+
\*
\w+\s*;
}mx;
my$source=读取文件\*数据;
而($source=~/$pattern/g){
我的$match=$1;
$match=~s/\s+//g;
打印“$match\n”;
}
__资料__
CMyClass myClassInstance;
CMyClass2<
int,
int
>MyClass2安装程序;
C:\Temp>t.pl
int
int,int
不过,我想您可能更喜欢以下内容:

my $pattern = qr{
    ^
    (
      \w+                    
      <\s*(?:\w+(?:,\s*)?)+\s*> 
      \s*
      \w+
    )
    \s*;
}mx;
my$pattern=qr{
^
(
\w+
\*
\w+
)
\s*;
}mx;
这将产生:

C:\Temp> t.pl
CMyClass<int> myClassInstance
CMyClass2< int, int > myClass2Instacen
C:\Temp>t.pl
CMyClass myClassInstance
CMyClass2myclass2安装

我会这样做


#!/usr/bin/perl -w
use strict;
use warnings;

local(*F);
open(F,$ARGV[0]);
my $text = do{local($/);};
my (@hits) = $text =~ m/([a-z]{3})/gsi;

print "@hits\n";
假设你有一些文本文件,比如

/home/user$ more a.txt a bb dkl jidij lksj lai suj ldifk kjdfkj bb bb kdjfkal idjksdj fbb kjd fkjd fbb kadfjl bbb bb bb bbd i

对于你的问题,使用同样的方法,一个具体的解决方案可能会是


#!/usr/bin/perl -w                                                                                                           
use strict;
use warnings;

my $text = <<ENDTEXT;
 CMyClass<int> myClassInstance;

CMyClass2<
int,
int
> myClass2Instacen;


CMyClass35<
int,
int
    > myClass35Instacen;

ENDTEXT

my $basename = "MyClass";
my (@instances) = $text =~ m/\s*(${basename}[0-9]*\s*\<.*?                                                                
                            (?=\>\s*${basename})                                                                          
                            \>\s*${basename}.*?;)/xgsi;

for(my $i=0; $i<@instances; $i++){
    print $i."\t".$instances[$i]."\n\n";
}


#!/usr/bin/perl-w
严格使用;
使用警告;
my$text=MyClass35Instancen;
尾语
my$basename=“MyClass”;
my(@instances)=$text=~m/\s*(${basename}[0-9]*\s*\\s*${basename})
\>\s*${basename}.*?;)/xgsi;

对于(我的$i=0;$iDirect链接到以下引用的部分:\G%27-in-a-regular-expression%3fopen我的$fh,$ARGV[0]比local(*F)好);open(F,$ARGV[0]);在示例中使用Perl::Critic。我在示例中尝试了Perl::Critic(安装有点麻烦)但是对于我的示例,它没有给出任何注释/警告/错误。另外,我注意到pre和代码块没有正确地转义我的左括号和右括号。。。

/home/user$ ./a.pl a.txt
dkl jid lks lai suj ldi kjd fkj kdj fka idj ksd fbb 
kjd fkj fbb kad fjl bbb bbd

#!/usr/bin/perl -w                                                                                                           
use strict;
use warnings;

my $text = <<ENDTEXT;
 CMyClass<int> myClassInstance;

CMyClass2<
int,
int
> myClass2Instacen;


CMyClass35<
int,
int
    > myClass35Instacen;

ENDTEXT

my $basename = "MyClass";
my (@instances) = $text =~ m/\s*(${basename}[0-9]*\s*\<.*?                                                                
                            (?=\>\s*${basename})                                                                          
                            \>\s*${basename}.*?;)/xgsi;

for(my $i=0; $i<@instances; $i++){
    print $i."\t".$instances[$i]."\n\n";
}