2016-07-22 87 views
3

我有一個多行字符串是這樣的:正則表達式,只有當匹配沒有重複的行發現

SA21 abcdef 
BKxyz 
SA21 abcdef 

我需要的,只有當行^SA21 abcdef$存在一次匹配的正則表達式。所以它不應該匹配的第一個例子,但它應該與這一個:

BK udsia 
SA21 abcdef 
BKxyz 

我試圖捕捉行,並確保它僅匹配在未後來發現在同一行:/(^SA21 abcdef$)(?!\1)/mregex101但也不不工作,因爲它可能總是匹配最後一行......

+2

嘗試['\ A(?:(?!^ SA21 abcdef $))。)*(^ SA21 abcdef $)(?:(?!^ SA21 abcdef $)。)* \ z'](https://www.regex101.com/r/vN4tQ9/1)(只是想知道是否是正確的方向)。 –

+2

爲什麼不匹配它,然後檢查那裏有多少匹配,併爲此做出「if」? –

+0

@FlorianPeschka我們用正則表達式從DSL – Chris

回答

2

你想要的正則表達式應該只匹配一個如果該行在單行發生之前或之後不存在。這是一個鍛鍊貪婪令牌實現:

/\A(?:(?!^SA21 abcdef$).)*(^SA21 abcdef$)(?:(?!^SA21 abcdef$).)*\z/ms 

regex demo

(?:(?!^SA21 abcdef$).)*是匹配任何文字,但SA21 abcdef行的開頭令牌。 /s修飾符是必需的,因此.可以匹配換行符。

但是,結構是比較消耗資源,這是一個好主意,把它打開:

/\A(?:\n+(?!SA21 abcdef$).*)*\n*^(SA21 abcdef)$(?:\n+(?!SA21 abcdef$).*)*\z/m 

another demo

注意\A\z有明確的開始/結束錨, /m修飾符不會影響它們。

模式闡釋

  • \A - 零個或多個序列 - 串
  • (?:\n+(?!SA21 abcdef$).*)*開始:
    • \n+ - 1個或多個新行...
    • (?!SA21 abcdef$) - 沒有跟着SA21 abcdef即全行
    • .* - 零個或多個字符比換行符其他
  • \n* - 零個或多個換行符
  • ^ - 線
  • (SA21 abcdef)的開始 - 即必須是單線路
  • $ - 行末
  • (?:\n+(?!SA21 abcdef$).*)* - 見上面
  • \z - 字符串結尾。
+1

完美的作品...非常感謝 – Chris