2016-03-02 88 views
1

我使用正則表達式如下解析我的應用程序日誌文件中搜索特定字符串做一個字符串確定特定字符的存在

\[\s*\b(?:[0-9A-Za-z][0-9A-Za-z-_.#]{0,200})(?:\.(?:[0-9*A-Za-z][0-9A-Za-z-_.#]{0,200}))*(\.?|\b)\s*] 

這工作得很好,但現在我們需要確保字符串「必須」包含匹配的「 - 」字符。我很困惑把這個條件添加到最初的regx。 任何指針都會有幫助。

感謝和問候, Santhosh

+0

是'-'應該是在特定的位置? – Trasiva

+0

@Trasiva,我們只需要確保存在。它不是位置特定的 – kallada

+0

我總是建立我的正則表達式查詢測試他們與這個偉大的工具:http://regexr.com/您可以看到,如果您的查詢是在實時工作,同時進行更改,使正則表達式a很容易:) – Kocik

回答

2

正則表達式方括號,[]內部的串相匹配,並且可以僅由非[和非]符號。

您可以像支票開[後輕鬆地添加了積極前瞻的限制,如果超過][等下一個字符,隨後用-

\[           # opening [ 
    (?=[^\]\[]*-)        # There must be a hyphen in [...] 
    \s*           # 0+ whitespaces 
    \b(?:[0-9A-Za-z][0-9A-Za-z-_.#]{0,200})  # Part 1 (with obligatory subpattern) 
    (?:\.          # Part 2, optional 
     (?:[0-9*A-Za-z][0-9A-Za-z-_.#]{0,200}) 
)* 
    (\.?|\b)         # optional . or word boundary 
\s*           # 0+ whitespaces 
]            # closing ] 

regex demo

而且一one-liner

\[(?=[^\]\[]*-)\s*\b(?:[0-9A-Za-z][0-9A-Za-z-_.#]{0,200})(?:\.(?:[0-9*A-Za-z][0-9A-Za-z-_.#]{0,200}))*(\.?|\b)\s*] 

提示:使用詳細的/x修飾符將模式分割爲單獨的多行塊進行分析,它將在將來需要再次修改模式時幫助您。

如果只有在-@存在於[...]內時才需要匹配,請將lookahead修改爲(?=[^\]\[]*[[email protected]])。對於更一般的情況,請在預覽內的其他組內使用(?=[^\]\[]*(?:one|another|must-be-present))替代方案。

+0

這是一個好主意,可以檢查代碼中的「黑客」,並且可以通過代碼本身添加其他(以及當前)限制。 –

+0

非常感謝。現在我遇到了一個需要檢查 - 或@的情況,以取得圓滿成功。所以我試圖修改(?= [^ \] \ [] * - )#這行中必須有一個連字符(?= [^ \] \ [] * - | @)#There必須是連字符或@中的[...]。但是這個表情還沒有考慮用@來刺激。 – kallada

+0

如果必須有'-'或'@',請將'lookahead'修改爲'(?= [^ \] \ [] * [ - @])''。 –

0

這個條件會工作,如果只是想確保 - 運行你的代碼塊之前,你的字符串中出現。

if (myString.indexOf('-') >= 0) { 
    //your code 
} 
+0

我們可以只用正則表達式嗎? – kallada

+0

是的,我們可以:)。 –

0

如果你必須有一個連字符,你就必須要麼重複大部分的圖案,或檢查它在第二階段:

if re.match(pattern, line): 
    if not '-' in line: 
     raise MissingDash('No dash in line: {}'.format(line)) 

我建議將第二請檢查,因爲向正則表達式添加要求會使其閱讀更加糟糕。

+0

爲什麼選擇Python?正則表達式讀起來並不可怕,這對我來說很清楚。 –

+0

他們使用* some *語言的正則表達式,Python在這個級別上很容易閱讀和理解。至於'爲什麼要用代碼',好吧,OP似乎可能更容易處理。 –

+0

我同意,但要求是一個要求。當不添加語言標籤時,給出特定語言的答案就像是在黑暗中拍攝的照片。真的,這個正則表達式並不可怕。當一個模式充滿了反向引用,lookaround和子程序調用(或平衡結構)時,情況會更糟糕。這是一個典型的線性模式,只包含字符類,組,量詞,文字符號。比它可能長一點,但是當分裂時,它是可讀的。 –

1

更新答案 - 斷言

在這種情況下,更好的方式來做到這一點是使用斷言包括檢查只預計有問題的字符相匹配的位置的的。

我知道這很簡單,但使用outter僞錨文本\[ ... \]
不能在體內存在的分隔符是一個罕見的。

你應該總是儘量避免這樣做。
事情變了,你的意見可能會改變。
規則已知字符是驗證遵循中間串只是其中
使用斷言驗證時使用。

這避免了依賴的必要性是什麼根本不存在的那一刻即不是]
而應該依靠什麼那裏。

同樣,這屬於中間字符串的匹配。
BOL/EOL是完全不同的東西^$,並且是一個更持久的構造
利用它。

智能代碼總是更好。

\[\s*\b(?=[0-9A-Za-z][0-9A-Za-z_.#]{0,199}-|[0-9A-Za-z][0-9A-Za-z_.#]{0,200}(?:\.[0-9*A-Za-z][0-9A-Za-z_.#]{0,200})*\.[0-9*A-Za-z][0-9A-Za-z_.#]{0,199}-)(?:[0-9A-Za-z][0-9A-Za-z_.#-]{0,200})(?:\.(?:[0-9*A-Za-z][0-9A-Za-z_.#-]{0,200}))*(\.?|\b)\s*\] 

使用條件語句

如果你的引擎支持條件語句,最簡單的方式是不依賴於僞錨文本,即僥倖
[..]

\[\s*\b[0-9A-Za-z](?:[0-9A-Za-z_.#]|(-)){0,200}(?:\.(?:[0-9*A-Za-z](?:[0-9A-Za-z_.#]|(-)){0,200}))*(\.?|\b)\s*\](?(1)|(?(2)|(?!)))

擴展

\[ \s* \b 
[0-9A-Za-z] 
(?: 
     [0-9A-Za-z_.#] 
    | (-)       # (1) 
){0,200} 
(?: 
     \. 
     (?: 
      [0-9*A-Za-z] 
      (?: 
       [0-9A-Za-z_.#] 
      | (-)       # (2) 
      ){0,200} 
    ) 
)* 
(\.? | \b)     # (3) 
\s* \] 

(?(1)       # Fail if no dash found 
    | (?(2) 
     | (?!) 
    ) 
) 
+0

不幸的是我不支持條件 – kallada