2013-10-08 53 views
1
eErrorT ChainCtrlInitChains(ChainCtrlT* pChainCtrl, 
    char* name, 
    int instance) 
{ 
    .... 
} 
eErrorT ChainCtrlInit(ChainCtrlT* pChainCtrl, void* pOwner) 
{ 
    .... 
} 

我的代碼perl的 - 從多線功能提取功能參數定義

open(my $FILE, "< a.c") or die $!; 
my @arr = <$FILE>; 
foreach(@arr){ 
    if ($_ =~ /^ \S+ \s+ \S+ \s* \((.+?) \) /xsmg) { 
     my $arg = $1; 
     my @arr = map /(\w+)$/, split /\W*?,\W*/, $arg; 
     print my @temp = map "$_\n", @arr 
      unless $_ =~ /;\s*$/; 
    } 
} 

基本上我提取函數從函數定義的參數。

但在這種情況下,我只能提取2次函數(ChainCtrlInit)而不是第一個函數(ChainCtrlinitchains)參數。

所需的輸出

pChainCtrl 
name 
instance 

pChainCtrl 
pOwner 

OUTPUT我得到

pChainCtrl 
pOwner 

回答

2

的問題是,你正在閱讀的行的文件在線等正則表達式永遠不能跨越多個線延伸 - 如果您加載該文件然後使其成爲一個單一的字符串與嵌入新行將它的工作

例如一個快速入侵

open(my $FILE, "< a.c") or die $!; 
my @arr = <$FILE>; 
my $file = join('',@arr); 

my @matches = $file =~ /^ \S+ \s+ \S+ \s* \((.+?) \) /xsmg; 
foreach (@matches) { 
     my $arg = $_; 
     my @arr = map /(\w+)$/, split /\W*?,\W*/, $arg; 
     print my @temp = map "$_\n", @arr 
      unless $_ =~ /;\s*$/; 
     print "\n"; 
    } 
+0

感謝..現在工作得很好。我是Perl新手。認爲它將從「(」直到它看到「)」開始檢查,即使它在單獨的行中。 –

+0

節省了大量的工作與我的'$文件= {做當地$ /; '而不是將它分成幾行以再次加入它們。 – cjm

4

你的問題是,當你做「的foreach」,$ _塊中繼承了陣列中的每個元素。 例如,

的foreach(@arr)..循環的第一次迭代中分配$ _與 「eErrorT ChainCtrlInitChains(ChainCtrlT * pChainCtrl,\ n」,讓你的正則表達式將失敗。

而且你還。沒有過多的使用使用臨時變量我有完善的代碼如下所示:

my $arr = do { local $/; <$FILE> }; #Copy one of the comments above. 

#note there's a slight difference in the 'while' regex to your code 
while ($arr =~ /^ \S+ \s+ \S+ \s* (\(.+? \)) /xsmg) { 
    my @args = $1 =~ /(\w+)[,)]/g; #This assumes what you want always ends in 
    #a ',' or a ')', hence the gentle modification in the 'while' regex. 
    local $" = "\n"; 
    say "@args"; 
} 
1

@廣告-VIC,除了@ atleypnorth的解決方案,整個文件啜入一個字符串,有可能是你的分割地圖語句中的一個問題。


my @arr = map /(\w+)$/, split /\W*?,\W*/, $arg;
應該是這個
my @arr = map /(\w+)\W*$/, split /\W*?,\W*/, $arg;
因爲分裂的最後一個元素獲得剩餘的字符。

一旦你的Perl的竅門,你可以簡化成這樣 -

$/ = ""; 
open(my $FILE, "< a.c") or die $!; 
my $str = <$FILE>; 

foreach ($str =~ /^ \S+ \s+ \S+ \s* \((.+?) \) /xsmg) { 
    print map "$_\n", /(\w+) [^\w,]* (?:,|$)/xg ; 
    print "\n"; 
} 
+0

只需注意,這不建議用於解析c/C++。 – sln