2011-08-31 42 views
0

我會盡力更好地解釋我自己;-)。JavaScript RegExp語法問題

我正在使用RegexBuddy嘗試查找解決方案。 目標是Konfabulator小部件中的JavaScript。

我需要解析該字符串是:

+++++++++++++++++++++ RUNWAY ++++++++++++++++++++++++++++++ 
1A1093/11 VALID: 1107140300 - 1108301500 
    DAILY 0300-1500 
    WIP 90M S OF RWY 08/26 AT E, W1, W2. 
    NO RESTRICTION DRG TKOF/LDG OR TAX. 
1A994/11 VALID: 1106201300 - 1112312059 
    PAPI RWY 08 NOT OPR WHEN ILS APCH IN USE. OPR WHEN VIS APCH IN 
    USE. 
1A987/11 VALID: 1106190615 - UFN 
    ILS DME RWY 08 BC 110.90MHZ CH46X OPR. 
+++ 

最終的結果應該是以下3子串:

子串1)

1A1093/11 VALID: 1107140300 - 1108301500 
    DAILY 0300-1500 
    WIP 90M S OF RWY 08/26 AT E, W1, W2. 
    NO RESTRICTION DRG TKOF/LDG OR TAX. 

子串2)

1A994/11 VALID: 1106201300 - 1112312059 
    PAPI RWY 08 NOT OPR WHEN ILS APCH IN USE. OPR WHEN VIS APCH IN 
    USE. 

子串3)

1A987/11 VALID: 1106190615 - UFN 
    ILS DME RWY 08 BC 110.90MHZ CH46X OPR. 

正如你可以看到每個部分有類似的東西開始「1A987/11有效的:」這是我現在用的這個正則表達式發現:

[0-9A-Z]{3,6}/\d{2}\s{1,3}VALID: 

每個部分與結尾的 「1A987/11 VALID:」 下一個部分的或用 「+++」 我正在使用此正則表達式發現:

([0-9A-Z]{3,6}/\d{2}\s{1,3}VALID:)|(\+{3}) 

的字符之間是[\ S \ S] +? 「。」由於某種原因不起作用。

所以完整的正則表達式是:

[0-9A-Z]{3,6}/\d{2}\s{1,3}VALID:[\s\S]+?(([0-9A-Z]{3,6}/\d{2}\\s{1,3}VALID:)|(\+{3})) 

現在,因爲串1的到底是子2的開始,使用RegexBuddy沒有找到子串2,只有串1和3被發現。

我正在尋找一種方法來查找所有3個子字符串,因此一種方法來查找每個子字符串的結束,但將其從字符串本身排除。

+0

這是用於NOTAM解碼器嗎? –

回答

0

我不是100%確定你的第二個VALID:在那裏做什麼,但我認爲你的正則表達式的第二部分在「|」之後, (或)你看起來像在試圖捕捉「UFN」的情況下,似乎缺少捕捉UFN的東西。我不知道這個序列的全部可能性,或者你正在使用哪個正則表達式的實現,但是如果你用[AZ]捕獲大寫字母,那麼你需要最後一個組是([AZ] {3 }),或者在斜線後面使用通用字母數字符號而不是加號。

0

這取決於我們在這裏談論的是什麼語言,但下面的正則表達式在Perl中適用於我的s擴展名,它將行尾視爲普通字符。

([0-9A-Z]{3,6}/\d{2}\s{1,3}VALID:.+?)([0-9A-Z]{3,6}/\d{2}\s{1,3}VALID:.+?)([0-9A-Z]{3,6}/\d{2}\s{1,3}VALID:.+?)(\+{3}) 

如果您正在嘗試查找某些數量的有效部分,那麼您必須執行一個依賴於語言的循環。

請注意,我已將[0-9]|[A-Z]摺疊爲[0-9A-Z],並基本上將第一個(...)圖案複製了3次。

+0

它在RegexBuddy中工作,但我沒有設法使它在JavaScript中工作。我以另一種方式放棄並解決了這個問題。 10倍的所有幫助。 – Erez

+0

+1將不勝感激。 – Gray

0

我不是很確定你使用的正則表達式解析器,但給這畜生一個鏡頭:

((?:(?:[0-9]|[A-Z]){3,6}/\d{2}\s{1,3}VALID:.+?)(?=(?: \+\+\+$|(?:[0-9]|[A-Z]){3,6}/\d{2}))) 

它採用積極的向前看符號,所以它可能會或可能不會爲你工作。

編輯:這是一個JavaScript多線測試:

var match, regex = /([0-9A-Z]{3,6}\/\d{2}\s{1,3}VALID:[\s\S]+?)(?=(?: \+{3}$|(?:[0-9A-Z]{3,6}\/\d{2})))/g; 
var s='+++++++++++++++++++++ RUNWAY ++++++++++++++++++++++++++++++\n\ 
1A1093/11 VALID: 1107140300 - 1108301500 \n\ 
    DAILY 0300-1500 \n\ 
    WIP 90M S OF RWY 08/26 AT E, W1, W2. \n\ 
    NO RESTRICTION DRG TKOF/LDG OR TAX. \n\ 
1A994/11 VALID: 1106201300 - 1112312059 \n\ 
    PAPI RWY 08 NOT OPR WHEN ILS APCH IN USE. OPR WHEN VIS APCH IN \n\ 
    USE. \n\ 
1A987/11 VALID: 1106190615 - UFN\n\ 
    ILS DME RWY 08 BC 110.90MHZ CH46X OPR. +++'; 

while (match=regex.exec(s)){ 
    alert(match[0]); 
} 
1

我看了你的問題的方式,顯著的事實是:

  1. 每場比賽包括兩個或更多的線;
  2. 第一行的開頭符合您給出的模式;和
  3. 每個後續行以空格開頭。

這是我會怎麼表達,作爲一個正則表達式:

/^[A-Z0-9]{3,6}/[0-9]{2}[ \t]+VALID:.*(\r?\n[ \t]+.*)+/mg 

注意我是如何用[ \t]+代替\s+VALID:前及後續行的開始,只匹配水平空白字符(空格和/或製表符)。然後我用\r?\n來匹配行分隔符(DOS樣式\r\n或Unix樣式\n)。這樣,我從來沒有比我需要的匹配更多,使正則表達式更高效,以及更易於編寫和調試。

m最後打開multiline模式,該模式允許^錨點在一行的開頭匹配。 g打開global模式,允許您查找所有匹配項,而不僅僅是第一個匹配項。

順便說一句,你必須使用[\s\S]而不是.的原因是因爲JavaScript沒有「單行」或「DOTALL」模式,正如大多數其他正則表達式所做的一樣。無法使.與回車符(\r)或換行符(\n)匹配。但是,如果您明確地匹配行分隔符,那麼您不必處理另一件事,就像我一樣。