Java正则表达式用于验证字符串。

3
我刚买了一本关于正则表达式的书,但我仍然很难理解。我正在尝试创建一个Java正则表达式,以满足以下字符串配置:
  1. 可以包含小写字母([a-z])
  2. 可以包含逗号(,),但只能在单词之间使用
  3. 可以包含冒号(:),但必须与单词或乘积(*)分开
  4. 可以包含连字符(-),但必须与单词分开
  5. 可以包含乘积(*),但如果使用,则必须是冒号之前/之间/之后的唯一字符
  6. 不能包含空格,“单词”由连字符(-)、逗号(,)、冒号(:)或字符串结尾分隔
例如,以下内容是正确的:
  1. foo:bar
  2. foo-bar:foo
  3. foo,bar:foo
  4. foo-bar,foo:bar,foo-bar
  5. foo:bar:foo,bar
  6. *:foo
  7. foo:*
  8. *:*:*
但以下内容是错误的:
  1. foo :bar
  2. ,foo:bar
  3. foo-:bar
  4. -foo:bar
  5. foo,:bar-
  6. foo:bar,
  7. foo,*:bar
  8. foo-*:bar
以下是我目前的代码:
^[a-z-]|*[:?][a-z-]|*[:?][a-z-]|*

10
你尝试过什么来完成这个目标吗? - Luiggi Mendoza
尝试一些东西并发布您的尝试,我们在这里帮助您。 - VictorCreator
1
将我的答案转换为评论,因为您要求的不是Java代码,但是这里有一个Web服务,您可以在线测试正则表达式:http://www.regexplanet.com/advanced/java/index.html。它是一个救命稻草。至少它节省了很多时间。除了您的书之外,您还应该记住Pattern类的javadoc:http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html - chburd
2个回答

3

这里有一个正则表达式,适用于你所有的情况:

([a-z]+([,-][a-z]+)*|\*)(:([a-z]+)([,-][a-z]+)*|\*)*

以下是详细的分析:

构建复杂正则表达式的基本结构之一其实非常简单,它的形式为text(separator text)*。这样的正则表达式将匹配:

  • 一个text
  • 一个text,一个separator和另一个text
  • 一个text,一个separator,另一个text,另一个separator和另一个text
  • 或更多,只需在末尾添加另一个separator和一个text

所以这里是代码的详细说明:

  • [a-z]+([,-][a-z]+)*是我上面讨论的模式的一个实例:这里的text[a-z]+separator[,-]
  • ([a-z]+([,-][a-z]+)*|\*)允许匹配星号。
  • ([a-z]+([,-][a-z]+)*|\*)(:([a-z]+([,-][a-z]+)*|\*))*是我上面讨论的模式的另一个实例:这里的text([a-z]+([,-][a-z]+)*|\*)separator:

如果您打算将其用作更大正则表达式的组件,并且组匹配非常重要,我建议使内部括号非组合,并在整个正则表达式周围放置组合括号,如下所示:

((?:[a-z]+(?:[,-][a-z]+)*|\*)(?::([a-z]+)(?:[,-][a-z]+)*|\*)*)

由于OP正在学习正则表达式,因此最好将其分解并解释其不同的组成部分,这样会更有益处。 - Shaz
如果您不介意将其分解,那将非常有帮助。 - tarka
@RyanWH 已经分解完毕。 - AJMansfield
非常感谢您抽出时间以这样建设性的方式进行分解,它非常有用。然而,我发现您发布的解决方案由于几个原因而不太适用。第一个可能是打字错误,因为它似乎在开头放置了一个多余的括号,而没有匹配的闭合括号。另一个问题是模式的第二个实例不允许“*”。如果您感兴趣,我修改了括号以匹配您的说明,现在它可以工作:([a-z]+([,-][a-z]+)*|\\*)(:([a-z]+([,-][a-z]+))*|\\*)* - tarka

2
很少有人能够定义正向和负向测试用例,这让生活变得更加轻松。下面是我的使用正则表达式的95%解决方案:
  • "(([a-z]+|\\*)[:,-])*([a-z]+|\\*)" (JAVA-Version)
  • (([a-z]+|\*)[:,-])*([a-z]+|\*) (plain regex)
它简单地区分单词(a-z或*)和分隔符(:-,之一),并且必须至少包含一个单词,并且单词必须用分隔符隔开。它适用于正向情况和所有负向情况,除了最后两个负向情况。
注意:在实际应用中,这样复杂的“语法”将使用ANTLR等语法定义工具来实现(或几年前使用lex/yacc、flex/bison)。正则表达式可以实现,但维护起来可能不容易。

+1 提到ANTLR,我以前从未听说过,但我会调查一下,因为它看起来非常有趣。 - tarka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接