2017-09-05 82 views
1

我想讀一個.java文件到Perl變量,我想匹配的功能匹配功能的全部文本,例如說:Perl的正則表達式 - 閱讀的java文件和文件

​​

這個模樣的正則表達式會是什麼樣子?

當前的嘗試:

use strict; 
use warnings; 

open (FILE, "example.java") || die "can't open file!"; 
my @lines = <FILE>; 
close (FILE); 

my $line; 

foreach $line (@lines) { 
if($line =~ /String example(.*)}/s){ 
    print $line; 
} 
} 
+0

不是很簡單。你有平衡的文本是範圍分隔符,可以隱藏在引號和註釋中。那麼,你至少需要考慮3件事情,並寫出一個非常龐大而複雜的正則表達式。我會收取錢來做這個。當然,該功能本身可以隱藏在評論或引用中。 – sln

+0

爲什麼?我的意思是說像這樣說會變得很複雜。但是什麼是垃圾?並且有多少匹配的字符串示例('在所有目錄中都有?)如果匹配少於20,則手動更快。 –

+0

這只是爲了替換文件中的函數,而不必手動執行,原因。 –

回答

2

** Adopted from this answer

正則表達式:

^\s*([\w\s]+\(.*\)\s*(\{((?>"(?:[^"\\]*+|\\.)*"|'(?:[^'\\]*+|\\.)*'|//.*$|/\*[\s\S]*?\*/(\w+)["']?[^;]+\4;$|[^{}<'"/]++|[^{}]++|(?2))*)})) 

擊穿:

^ \s* 
(       # (1 start) 
    [\w\s]+ \(.* \) \s*     # How it matches a function definition 
    (       # (2 start) 
     \{          # Opening curly bracket 
     (       # (3 start) 
      (?>        # Atomic grouping (for its non-capturing purpose only) 
       "(?: [^"\\]*+ | \\ .)*"  # Double quoted strings 
      | '(?: [^'\\]*+ | \\ .)*'  # Single quoted strings 
      | // .* $      # A comment block starting with // 
      | /\* [\s\S]*? \*/    # A multi-line comment block /*...*/ 
       (\w+)      # (4)^
       ["']? [^;]+ \4 ; $   #^
      | [^{}<'"/]++     # Force engine to backtrack if it encounters special characters (possessive) 
      | [^{}]++      # Default matching behavior (possessive) 
      | (?2)       # Recurs 2nd capturing group 
      )*        # Zero to many times of atomic group 
    )        # (3 end) 
     }          # Closing curly bracket 
)        # (2 end) 
)        # (1 end) 
+0

這真的很糟糕 – Borodin

+0

不,不是真的。 – revo

+1

好的正則表達式revo! – sln

1

Revo的正則表達式是正確的做法(就像正則表達式一樣!)。

但有時您只需要快速操作一個您可以控制的文件。我發現,在使用正則表達式時,定義「足夠好」通常很重要。

因此,假定縮進是正確的,可能是「足夠好」。在這種情況下,你可以檢測FN的開始,接着看,直到你用相同的縮進找到下一個右花:

(    # Capture \1. 
    ^([\t ])+ # Match and capture leading whitespace to \2. 
    (?:\w+\s*)? # Privacy specifier, if any. 
    \w+\s*\( # Name and opening round brace: is a function. 
    .*?   # Need Dot-matches-newline, to match fn body. 
    \n\2}  # Curly brace is as indented as start of fn. 
)    # End capture of \1. 

應該是你自己寫乾淨的代碼工作,代碼,您可以通過首先是自動格式化程序等。

將與K & R,Hortmann和Allman indent styles一起使用。

將失敗單線和內聯功能,以及像GNU,Whitesmiths,Pico,Ratliff和Pico這樣的縮進樣式 - Rico的答案完全沒有問題。

對於使用泛型的lambda函數,嵌套函數和函數也失敗了,但即使Revo's也無法識別這些,並且它們並不常見。

而我們的正則表達式都不會捕獲函數前面的註釋,這是相當有罪的。

+1

這似乎很整潔! –

+0

@ConorThompson Neater也許,但只是因爲我對我們正在使用的數據做出了假設。所以我的建議遠不如Revo的代碼那麼堅固,它完全不會對格式化做出任何假設。即使那樣,他們都不是PHP解析器,所以在某些情況下都會中斷; Revo的休息時間遠遠少於*個案例。 –