2016-07-22 235 views
4

我需要允許給定字符串中的字母數字字符"?","." , "/""-"。但是我只需要限制連續的-使用Java正則表達式限制連續字符

例如:

  1. www.google.com/flights-usa應該是有效的

  2. www.google.com/flights--usa應爲無效

目前我正在使用^[a-zA-Z0-9\\/\\.\\?\\_\\-]+$

請教我如何限制連續-只。

+1

您是否必須使用單個正則表達式?爲什麼不只是's.matches(「[ - ?./ a-zA-Z0-9] +」)&&!!s.contains(「 - 」)'? – VGR

回答

3

您可以使用與量詞分組:

^[a-zA-Z0-9/.?_]+(?:-[a-zA-Z0-9/.?_]+)*$ 

regex demo

詳細

  • ^ - 字符串的開始
  • [a-zA-Z0-9/.?_]+ - 1或更多字符定義的集合在字符類(可以與[\w/.?]+代替)
  • (?:-[a-zA-Z0-9/.?_]+)* - 零個或更多個序列((?:...)*):
    • - - 連字符
    • [a-zA-Z0-9/.?_]+ - 見上文
  • $ - 的端串。

或者使用負前瞻:

^(?!.*--)[a-zA-Z0-9/.?_-]+$ 
^^^^^^^^^ 

demo here

詳細

  • ^ - 串
  • 開始
  • (?!.*--) - 一個負先行一旦正則表達式引擎比換行符
  • [a-zA-Z0-9/.?_-]+其他任何0+字符之後發現一個--子串,將失敗的匹配 - 從所述一組1或多個字符在字符類
  • $定義 - 字符串的結尾。

注意[a-zA-Z0-9_] = \w如果你不使用Pattern.UNICODE_CHARACTER_CLASS標誌。所以,第一個看起來像"^[\\w/.?]+(?:-[\\w/.?]+)*$",第二個看起來像"^(?!.*--)[\\w/.?-]+$"

+0

僅供參考:在角色類中,不需要轉義所有非單詞字符。 '/'根本不是特殊字符,連字符不必在字符類末尾轉義,字符類中的點和'?'失去其特殊含義,'_'是一個字字符 –

+0

從上面工作的唯一正則表達式就是這個'^(!!。* - )[a-zA-Z0-9 /.?_-]+$' – sln

0

我不確定這種效率,但我相信這應該起作用。

^([a-zA-Z0-9\/\.\?\_]|\-([^\-]|$))+$

對於每一個字符,此正則表達式檢查它是否可以匹配[a-zA-Z0-9\/\.\?\_],這是你在你的正則表達式,除了連字符包括一切。如果不匹配,則會嘗試匹配\-([^\-]|$),該匹配符號後面沒有連字符或連字符末尾有連字符。

Here's a demo.

1

的一種方法是限制在破折號具有負向後看多個破折號,像這樣:

^(?:[a-zA-Z0-9\/\.\?\_]|(?<!-)-)+$ 

|的右側,即(?<!-)-,意思是「一個破折號,除非在另一個短劃線之前「。

Demo.