2016-07-22 36 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.