2014-09-20 96 views
1

我打算在Java中使用REGEX來匹配字符串。例如我有字母'A' 'A' 'A' 'P' 'P' 'L' 'E' 'S'如何匹配字符串中的特定字符n-m次

我想檢查一個字符串是否包含0-3 'A', 0-2 'P', 0-1 'L', 0-1 'E' and 0-1 'S'。字符串的

例子,其應通過檢查: APPLE, APPLES, ALE, PALE... etc

這是我已經試過:

if (str.matches("[A]{0,3}[P]{0,3}[L]{0,1}[E]{0,1}[S]{0,1}")) 

APPLES通過檢查順利通過,但不SAPPLE

回答

1

你正在對你的信件施加一個特定的順序(在P之前的P之前的A之前的E,這就是爲什麼APPLES通過而不是SAPPLE)。其實,我不確定你想要做什麼甚至可以用合理的短正則表達式。我會用一個單獨的循環和一個Map來手動計算出現次數。

+0

你知道如何去除我的代碼中的特定順序嗎?我可以使用循環的傳統方式,但我認爲它可能不是很有效,因爲我有可能從字典中檢索超過50,000個單詞。 – user3437460 2014-09-20 01:55:21

+0

除非你的代碼在洗衣機上運行,​​否則5萬字是花生。如果沒有循環,你認爲正則表達式是如何匹配的? – Thomas 2014-09-20 06:45:45

3
(?!(.*A){4,})(?!(.*P){3,})(?!(.*L){2,})(?!(.*E){2,})(?!(.*S){2,})^[APLES]*$ 

試試這個。這將適用於你。參見演示。

http://regex101.com/r/sH6aF3/2

它使用負前瞻,以確保

A不該來先行的保證其他conditions.In結束的4個或更多times.Similarly休息時只選擇了它的時間消耗串[]內的字符是允許的。

+0

我甚至沒有...但是你是對的,這是正確的。如果你添加了關於它是如何工作的解釋,OP可能會有所幫助。 +1來回答這個問題,但是一個正則表達式可能仍然是錯誤的方式。 – Thomas 2014-09-20 06:45:13

2

優化的vks's regex版本:

^(?!(?>[^A]*A){4})(?!(?>[^P]*P){3})(?!(?>[^L]*L){2})(?!(?>[^E]*E){2})(?!(?>[^S]*S){2})[APLES]*$ 

變化:

  • 感動^錨前面。
  • 將捕獲組更改爲原子組以防止回溯 - 當字符串不匹配時可能會大幅提升性能。
  • 使用[^A]*A等組代替.*回溯以有效地滾動匹配。

這是regex demo

+0

仍然有很多學習離我4 :) – vks 2014-09-20 07:24:04

+0

這是如此酷:) thanx。將通過他們 – vks 2014-09-20 07:29:33

+1

我怎麼能監督這個看起來很熟悉的謎語:]你計算步驟似乎確實更高效,而@ vks'更緊湊一點,[我的](http:///regex101.com/r/iR2hI2/1)將再次成爲關於效率的事情。那麼沒有測試那麼多。 – 2014-09-21 05:30:26

相關問題