2017-09-01 44 views
0

假設我有一個數據存儲或歸檔系統,我接受了幾個格式(傳統的原因,不是我自己設計)在Regex中,你如何將重複組的一部分與前一個重複的部分進行匹配?

因此,舉例來說,我需要接受

abcd.efgh.1234.4567 
abcd-efgh-1234-4567 
abcd|efgh|1234|4567 

但不

abcd.efgh-1234|4567 

基本上我需要對我使用的分隔符保持一致。我試圖構建一個可以檢查的正則表達式,但我發現它非常棘手。我已經探索了正則表達式的引用,看看他們將如何尋找像abc-abc-abc重複的工作,但對我來說,我需要它允許abcd部分是不同的,只有確保我有同樣的分隔符

這裏就是我到目前爲止(link to Regex101);

(([a-z1-9]){4}([\.:|])){3}(([a-z1-9]){4}) 

我需要以某種方式給一個反向引用到([\.:|]),但我不能把它放在那裏,因爲它需要重複自身。

無論如何要在正則表達式中做到這一點?

回答

1

您可以捕獲定界符首次出現時,再後來回到引用它:

[a-z1-9]{4}([.:|])(?:[a-z1-9]{4}\1){2}[a-z1-9]{4} 

參看regex demo

  • [a-z1-9]{4}匹配長度四個字;
  • ([.:|])匹配並捕獲分隔符;
  • (?:[a-z1-9]{4}\1){2}捕獲第二和第三模式,分隔符被稱爲上面捕獲的分隔符;
  • [a-z1-9]{4}匹配最後的單詞;
1

你的正則表達式可能是\w+([.|-])\w+\1\d+\1\d+參見:example 1

它採用反向引用\ 1到第一次遇到分隔符(| 「」 「」 或 「 - 」)

測試:

$ cat repeat.txt 
abcd.efgh.1234.4567 
abcd-efgh-1234-4567 
abcd|efgh|1234|4567 
abcd.efgh-1234|4567 

結果:

$ grep -P '\w+([.|-])\w+\1\d+\1\d+' repeat.txt 
abcd.efgh.1234.4567 
abcd-efgh-1234-4567 
abcd|efgh|1234|4567 

或者,更通用的:

$ grep -P '\w+(\W)\w+(\1\w+)+' repeat.txt 
abcd.efgh.1234.4567 
abcd-efgh-1234-4567 
abcd|efgh|1234|4567 

參見:example 2。然而,最後一個問題可能是重複組只捕獲最後一次發生。

+0

謝謝,我想這個工程,但我期待/希望更通用的東西 – CodyBugstein

+0

更通用?像https://regex101.com/r/FlfRFI/2一樣? –

+0

不,我想用正則表達式來匹配內部組的一部分。在你寫的表達式中(這在任何情況下都是很好的),它可以重複自己,如果我的輸入涉及更多的字符集,那麼它就不會那麼好,例如'abcd-efgh-ijkl-mnop-qrs' – CodyBugstein

相關問題