2010-07-26 20 views
0

假設我有以下的測試字符串:使用正則表達式找到兩個分隔符之間單詞的任何最後一次出現

Start_Get_Get_Get_Stop_Start_Get_Get_Stop_Start_Get_Stop

其中_是指任何字符,如:StartaGetbbGetcccGetddddStopeeeeeStart ....

我想要提取的是Start和Stop分隔符中Get字的最後一次出現。這裏的結果是下面三個加粗的Get。

Start__Get__Get__ 獲取 __Stop__Start__Get__ 獲取 __Stop__Start__ 獲取 __Stop

我準確的,我想這樣做只是使用正則表達式,並儘可能在一個單一的通行證。

任何建議,歡迎

謝謝

+0

「我確切地說,我只想使用正則表達式並儘可能一次性完成此操作。」 - 爲什麼?這個正則表達式的味道是什麼? (因爲不同的版本支持不同的結構) – 2010-07-26 13:41:01

+0

你使用什麼語言 – NullUserException 2010-07-26 13:48:29

+0

正則表達式,因爲我需要擴展一個使用正則表達式開發的現有通用工具。它使用.NET Framework System.Text.RegularExpressions,但我不能確切地說它是什麼味道...可能是微軟的一個。 – Jerome 2010-07-26 13:50:33

回答

1
Get(?=(?:(?!Get|Start|Stop).)*Stop) 

我假設你StartStop分隔符永遠是正確的平衡,他們不能嵌套。

+0

這正是我需要的!謝謝'艾倫摩爾。 – Jerome 2010-07-26 20:25:50

+0

嗨艾倫,我試過你的解決方案的這個變種:Get(?=(?:(?! Get)。)*停止),它似乎也在工作。因爲(假設分隔符正確平衡,因爲您提到)需要更改(Get | Start | Stop),所以需要在搜索的Get和後綴之間沒有其他Get? – Jerome 2010-07-27 08:04:25

+0

'開始'是爲了防止匹配不在分隔符之間的'Get',比如'Get_Start_Stop'。至於「停止」,假設在最後一個「停止」之後有一大堆文本。您不希望'。*'一路走到最後,只能回溯大部分距離以匹配「停止」。 Lookaheads可能很滑;值得多加註意,以確保它們只在你需要的時候看起來遙遙領先。 – 2010-07-27 09:13:34

0

我會用兩道做了。第一遍查找單詞「Get」,第二遍查詢它的出現次數。

+0

感謝'PolyThinker,但我可以按照您的建議分兩步來處理它,但我想知道是否可以一次性完成... – Jerome 2010-07-26 13:33:10

0
$ echo "Start_Get_Get_Get_Stop_Start_Get_Get_Stop_Start_Get__Stop" | awk -vRS="Stop" -F"_*" '{print $(NF-1)}' 
Get 
Get 
Get 
+0

感謝'ghostdog,但我真的只需要正則表達式... – Jerome 2010-07-26 13:34:01

0

事情是這樣的,也許:

(?<=Start(?:.Get)*)Get(?=.Stop) 

這就需要可變長度的回顧後支持,這並不是所有的正則表達式引擎支持。
通過將第一個*更改爲{0,99}或類似方法,可以使其具有最大長度,其中多個(但仍然不是全部)支持。

此外,在前瞻中,根據雙下劃線是否爲拼寫錯誤,可能.應該是.+.{1,2}

+0

AFAIK,'{0,99}'技巧只適用於Java(即它支持有界的可變長度lookbehind)。但是你很幸運:OP使用的是.NET,這是支持*無界* lookbehind(另一個是JGSoft)的兩種風格之一。 – 2010-07-26 20:18:10

0

用Perl,我會怎麼做:

my $test = "Start_Get_Get_Get_Stop_Start_Get_Get_Stop_Start_Get_Stop"; 
$test =~ s#(?<=Start_)((Get_)*)(Get)(?=_Stop)#$1<FOUND>$3</FOUND>#g; 
print $test; 

輸出:

Start_Get_Get_<FOUND>Get</FOUND>_Stop_Start_Get_<FOUND>Get</FOUND>_Stop_Start_<FOUND>Get</FOUND>_Stop 

你應該適應您正則表達式的味道。

相關問題