2017-02-12 78 views
0

我試圖發現一個模式(在Ruby源代碼文件中),但是如果在內聯註釋中發現(即在#字符之後)則忽略該模式。正則表達式在給定字符後忽略模式

例如,給定本文 foo.bar foo foo::bar # foo.bar foo::bar

我想第一(foo.bar)和foo第三(foo::bar)的情況下被捕獲,其餘忽略(第二不具有立即尾隨.::,第四次和第五次出現後#,因此應該被忽略。

對於這樣的文字, foo.bar foo foo::bar

它應該仍然以相同的方式拾取第一個和第三個(因爲沒有要忽略的評論)。

我有各種各樣的技術,得到這件事,但沒有滿足所有情況下。後視是有希望的,但無法處理我的正則表達式方言(Ruby)中的變量長度。

因此,((?<!\#.*)foo[\.|:{2}])不會工作,因爲它是可變長度(並且,作爲寫,只會排除#反正後的第一個實例)

(.+?(?=#))被看好過了,所以我想((foo(\.|\:{2})).+)?(?=\#),這就是接近,但沒有看到區分在第一個之後有2個foo。比賽組只返回foo.bar foo foo::bar,但它確實忽略了#之後的任何內容。我很確定這是造成差距的.+,但其他修正似乎並沒有讓我更接近。

很明顯,我沒有得到如何去之後,開始懷疑是否有可能。

[編輯:添加第二個例子]

回答

0

我不Ruby的工作,但是從你的描述聽起來像Ruby不支持無界量詞lookbehinds。這當然會讓它更加困難。但是,您可以利用無限的預覽。你可以有檢查沒有行內註釋foo_bar個正則表達式:

^[^#]*foo(?:\.|::)bar(?=[^#]*$) 

...和檢查foo_bar s表示確實有內部註釋的正則表達式:

foo(?:\.|::)bar(?=[^#]*#) 

。 ..只是把它們放在一起交替:

foo(?:\.|::)bar(?=[^#]*#)|^[^#]*foo(?:\.|::)bar(?=[^#]*$) 
+0

好主意!我有兩個案件分開工作,但沒有考慮將這樣一個「大」對組合在一起的交替。我會嘗試,thx! – rdnewman

+0

你做了一件我想確定我明白的事情。兩個子句中的'?= [^#] *'是爲了確保在'$'或第一個'#'之前沒有遇到註釋,是正確的嗎?我嘗試過'?=。*#',但是這太過分了。我也爲後面的部分嘗試了'* [$ |#]',它也沒有工作。你能否多解釋一下,或者直接給我一個合適的資源?謝謝! – rdnewman

+0

正確。點星有問題,因爲點匹配任何東西,「任何東西」包括「#」。你可以通過使用一個非貪婪的星點('。*?')來緩解這個問題。「不哈希」或非貪婪的點星應該工作 - 這是一個問題或偏好。 –