2016-12-20 95 views
1

我試圖從模式XYX之後的字符串中提取3個字母的所有可能組合。正則表達式中的重疊匹配 - 斯卡拉

val text = "abaca dedfd ghgig" 
val p = """([a-z])(?!\1)[a-z]\1""".r 
p.findAllIn(text).toArray 

當我運行該腳本,我得到:

ABA,DED,GHG

它應該是:

ABA,ACA,DED,DFD,GHG,演出

它不檢測重疊組合。

+1

您確定需要任何3個字母的組合嗎?我希望第三個字母與第一個字母相同。 –

+0

正則表達式的Scaladoc表示查看findAllIn上的文檔,例如重疊匹配。 http://www.scala-lang.org/api/current/scala/util/matching/Regex.html#findAllIn(source:CharSequence):scala.util.matching.Regex.MatchIterator –

回答

2

您需要捕捉整個圖案並將其放入積極的向前看。 Scala中的代碼將是如下:

object Main extends App { 
    val text = "abaca dedfd ghgig" 
    val p = """(?=(([a-z])(?!\2)[a-z]\2))""".r 
    val allMatches = p.findAllMatchIn(text).map(_.group(1)) 
    println(allMatches.mkString(", ")) 
    // => aba, aca, ded, dfd, ghg, gig 
} 

online Scala demo

注意反向引用將轉向\2爲組檢查將ID = 2和第1組包含您需要的值去收集。

+0

我在CH的回答下面閱讀了您的意見,並且必須告訴您,regexr.com僅支持普通的JS正則表達式,而沒有實際建議*已知限制的任何*解決方法。其中一個限制是能夠收集零寬度匹配,即使它們包含非空捕獲的組。見[Regexr.com顯示我的正則表達式可以匹配0個字符,因此無限匹配](http://stackoverflow.com/questions/34495675/zero-length-regexes-and-infinite-matches/34495840#34495840)。要在那裏使用它,只需在末尾添加一個'.':['(()] (?!\2)[az]\2))./g'](http: regexr.com/3etul)。 –

+0

如果你在Sublime Text中解釋你需要處理字符串和正則表達式,我可能會提供幫助。你想創建這些重疊文本的列表,並刪除所有文字? –

3

的方式包括以包圍整個圖案在先行只消耗的開始位置:

val p = """(?=(([a-z])(?!\2)[a-z]\2))""".r 
p.findAllIn(text).matchData foreach { 
    m => println(m.group(1)) 
} 

的先行僅針對當前位置和內側的圖案的斷言(測試)不消耗字符。您要查找的結果位於第一個捕獲組中(因爲整個比賽都是空的,所以需要獲取結果)。

+0

這就是它,謝謝。它工作完美。 正則表達式是驚人的,看起來像黑魔法給我。這個概念讓我頭腦發熱仍然有問題。當我嘗試在Sublime Text搜索等一些工具中使用此模式時,或者http://regexr.com/不起作用。所以我必須更好地理解這一點。 ps:我需要這個幫助我解決第7天出現的代碼。 http://adventofcode.com/2016/day/7 –

+0

@oxcarh:你必須明白,一個前瞻斷言只是一個測試,並不會消耗字符(換句話說,整個匹配總是一個空字符串)。它適用於崇高的文本(我剛剛測試過),但給regexr.com一個錯誤(這可能是越野車)。 –