2013-07-18 15 views
4

我不明白爲什麼這不會導致"test"並希望得到一個解釋:[R VS sed的正則表達式的貪婪

a = "blah test" 
sub('^.*(test|$)', '\\1', a) 
# [1] "" 

比較它sed表達:

echo 'blah test' | sed -r 's/^.*(test|$)/\1/' 
# test 
echo 'blah blah' | sed -r 's/^.*(test|$)/\1/' 
# 

FWIW ,以下達到我想要的R(和上面的sed結果相同):

sub('^.*(test)|^.*', '\\1', a) 
+0

@agstudy我試圖匹配'測試'或行尾 - 正如你可以看到'sed'理解這個邏輯。我不明白你爲什麼說'(test | $)== $'?我添加了一個我想要的編輯。 – eddi

+0

@agstudy強調我不理解你寫的東西,嘗試運行'sub('(test | $)','bb',a)',其中R當然不會解釋爲'sub' $','bb',a)' – eddi

+0

儘管這不會改變結果,但有一點需要注意的是R使用擴展正則表達式和sed(Ubuntu 12.04 64位上的4.2.1)默認情況下使用基本正則表達式。正如我所說的,'echo'blah test'| sed -r's /^.*(test | $)/ \ 1 /')'產生相同的輸出。 –

回答

2

開始即貪婪.*,然後嘗試匹配(test|$),即無論是串文字'測試'或字符串的結尾。由於第一個貪婪匹配.*匹配的所有字符,它back-references一個字符,然後再次嘗試匹配(test|$),這裏$匹配字符串的結尾。

造成你的比賽結果是一個end of line character

我覺得sed使用POSIX NFA它試圖找到一個輪換,從R不同,這似乎使用傳統NFA

最長匹配
+0

謝謝;我誤解了傳統vs POSIX NFA,因爲'(set | setvalue)'和'(setvalue | set)'在'sed'和'R'中完全相同的方式匹配,據我所知(測試匹配on '設定值')...? – eddi

+1

儘管兩者似乎都使用NFA,但它們的實現可能會有細微的變化,在某些情況下證明其速度比另一種更快。 也讀取 http:// stackoverflow。COM /問題/ 12100588 /不一致之間-SID-和蟒蛇正則表達式 – Akash

5

您需要標記regex engine配襯的所有字符右高達字符串結束的^.*non-greedy

> sub('^.*?(test|$)', '\\1', "blah test") 
[1] "test" 
> sub('^.*?(test|$)', '\\1', "blah blah") 
[1] "" 
+0

你的意思是非貪心...... –

+0

@JoshuaUlrich,我不確定我的意思。也許我的意思是_lazy_。 – GSee

+0

@Gee yes yu make'。*''lazy'。 – agstudy