2014-04-13 21 views
2

我試圖創建一個正則表達式如下:Perl的正則表達式來查找關鍵字,而不是變量

print $time . "\n"; - >比賽只打印因爲時間是一個變量($)之前

$epoc = time(); - >只匹配時間

我現在的正則表達式是/(?-xism:\b(print|time)\b)/g,但它在第一個示例中匹配$ time的時間。

Check here.

我試過的東西[^ \ $]但後來它不匹配打印了。

(我將有更多的像打印關鍵字|時間| ... | ...)

感謝

+1

我不知道,如果你正在做的是正確的,但因爲在我看來,你只需要一個[負面後代](http://stackoverflow.com/q/22937618):'(?<!\ $)'。 [見演示](http://regex101.com/r/oG8pF6) – HamZa

+1

謝謝你正是這個。發佈它作爲答案,我會驗證它。 – anasaitali

回答

3

你需要的是一個負回顧後(?<!\$),它是零寬度,從而不會「消耗」字符。

(?<!\$)a表示匹配a如果沒有在文字$之前。請注意,我們逃過了$,因爲它意味着字符串結束(或根據m修飾符的行)。

你的正則表達式看起來像(?-xism:\b(?<!\$)(print|time)\b)

我想知道爲什麼你要關閉xism修飾符。他們默認關閉。
所以只需使用/\b(?<!\$)(?:print|time)\b/g作爲模式。

Online demo SO regex reference

+0

我使用xism是因爲在我的Perl代碼中,我正在做'''$ var = qr/\ b(?<!\ $)($ words)\ b /''' – anasaitali

7

解析Perl代碼是一種常見的和有用的教學工具,因爲學生必須瞭解的解析技術,他們正試圖解析代碼。

然而,要做到這一點正確,最好的建議是使用PPI

下面的腳本解析本身並輸出所有的裸字的。如果你願意,你可以將裸字列表與你試圖匹配的列表進行比較。請注意,這將避免中的字符串,評論的事情,等

use strict; 
use warnings; 

use PPI; 

#my $src = do {local $/; <DATA>}; # Could analyze the smaller code in __DATA__ instead 
my $src = do { 
    local @ARGV = $0; 
    local $/; 
    <>; 
}; 

# Load a document 
my $doc = PPI::Document->new(\$src); 

# Find all the barewords within the doc 
my $barewords = $doc->find('PPI::Token::Word'); 
for (@$barewords) { 
    print $_->content, "\n"; 
} 

__DATA__ 
use strict; 
use warnings; 

my $time = time; 

print $time . "\n"; 

輸出:

use 
strict 
use 
warnings 
use 
PPI 
my 
do 
local 
local 
my 
PPI::Document 
new 
my 
find 
for 
print 
content 
__DATA__ 
+0

** + 1 ** for不使用正則表達式 – HamZa

+0

這看起來不錯,但我不能使用它(''無法找到@ INC'''中的PPI.pm)。我只能使用已安裝的模塊。 – anasaitali

+0

我一直注意到你的優良正則表達式風格,但這個解決方案不是正則表達式!提升原創性和指導性解決方案... Perl對我來說很神祕。:) – zx81