3

我刚刚买了一本关于正则表达式的书,试图了解它,但我仍然在努力解决它。我正在尝试创建一个满足字符串配置的java正则表达式;

  1. 可以包含小写字母 ([az])
  2. 可以包含逗号 (,) 但只能在单词之间
  3. 可以包含冒号 (:) 但必须用单词分隔或乘 (*)
  4. 可以包含连字符 (-) 但必须用单词分隔
  5. 可以包含乘法 (*) 但如果使用它必须是冒号之前/之间/之后的唯一字符
  6. 不能包含空格,“单词”由连字符 (-) 或逗号 (,) 或冒号 (:) 或字符串结尾分隔

因此,例如以下情况是正确的:

  1. 富:酒吧
  2. 富酒吧:富
  3. 富,酒吧:富
  4. 富酒吧,富:酒吧,富酒吧
  5. 富:酒吧:富,酒吧
  6. *:富
  7. 富:*
  8. *:*:*

但以下是错误的:

  1. 富:酒吧
  2. ,foo:酒吧
  3. foo-:bar
  4. -foo:酒吧
  5. 富,:酒吧-
  6. 富:酒吧,
  7. 富,*:酒吧
  8. foo-*:bar

这是我到目前为止所拥有的:

^[a-z-]|*[:?][a-z-]|*[:?][a-z-]|*
4

2 回答 2

3

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

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

下面是详细分析:

用于构建像这样复杂的正则表达式的基本结构之一实际上非常简单,并且具有. 该形式的正则表达式将匹配:text(separator text)*

  • 一个文本
  • 一个文本、一个分隔符和另一个文本
  • 一个文本,一个分隔符,另一个文本,另一个分隔符,还有另一个文本
  • 或更多,只需在末尾添加另一个分隔符文本

所以这里是代码的细分:

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

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

((?:[a-z]+(?:[,-][a-z]+)*|\*)(?::([a-z]+)(?:[,-][a-z]+)*|\*)*)
于 2013-09-12T15:37:13.293 回答
2

我们在这里很少看到有人可以定义正面和负面的测试用例。这让生活变得更加轻松。

这是我的正则表达式,有 95% 的解决方案:

  • "(([a-z]+|\\*)[:,-])*([a-z]+|\\*)"(JAVA-版本)
  • (([a-z]+|\*)[:,-])*([a-z]+|\*)(普通正则表达式)

它只是区分单词(az 或 *)和分隔符(:-, 之一),它必须至少包含一个单词,并且单词必须用分隔符分隔。它适用于正面案例和负面案例,除了最后两个负面案例。

一句话:如此复杂的“语法”将在现实生活中使用像 ANTLR 之类的语法定义工具(或几年前使用 lex/yacc、flex/bison)来实现。正则表达式可以做到这一点,但不容易维护。

于 2013-09-12T15:23:48.827 回答