2

我正在尝试为内部标记语言开发代码验证系统,但由于我对正则表达式没有经验,我遇到了一些麻烦。语言中的标签遵循以下格式:

{ 标签:数字:短语 1 | 短语 2 ... | 短语 n}

其中 number 是 (3.0, 3.5, 4.0 ... 8.5) 范围内的数字,并且其中一个短语的末尾必须有一个星号,并且必须至少有两个短语。请注意,标签不区分大小写,空格无关紧要。

我正在使用的正则表达式是:

\{ ?(mw) ?: ?[3-8]{1}(.0|.5)? ?((((\| ?(\w ?)+[\p{P}]? ?)*)+((\| ?(\w\ ?)+[\p{P}]?)* ?\* ?)+((\| ?(\w ?)+[\p{P}]? ?)*)?)|(((\| ?(\w ?)+[\p{P}]? ?)*)?((\| ?(\w ?)+[\p{P}]?)* ?\* ?)+((\| ?(\w ?)+[\p{P}]? ?)*)+))( ?\})

这确实符合以下正确情况:

{ mw : 3.5 | phrase 1 | phrase 2* | phrase 3}

还有以下不正确的情况:

{ mw : 3.5 | phrase 1* | phrase 2* | phrase 3} [Two asterisks]

{ mw : 3.5* | phrase 1 | phrase 2* | phrase 3} [An asterisk with the number value]

谢谢你的帮助。

如果有人想提供有关数据验证系统通常如何工作的任何见解,我将不胜感激。

4

2 回答 2

1

这看起来像是一个正确语法的地方,并使用诸如 yacc、antlr...ect 之类的解析工具来构建将实际为您进行解析的代码。正则表达式只能做这么多,但看起来你的 DSL 的定义可能不准确。

否则您将需要使用多个正则表达式来验证使用单个表达式无法找到的特殊情况。

于 2012-07-09T14:29:28.460 回答
0

这里:

\{\s*(\w+)\s*:\s*([3-8]\.[05])\s*(\|[^|*\n]*)*(\|[^|*\n]*\*\s*)(\|[^|*\n]*)*\}

这是一个演示,使用以下输入进行测试:

{ mw : 3.5  | hello,  world  | says  | i  }
{ mw : 3.5  | hello,* world  | says  | i  }
{ mw : 3.5  | hello,  world* | says  | i  }
{ mw : 3.5  | hello,  world  | says* | i  }
{ mw : 3.5  | hello,  world  | says  | i* }
{ mw : 3.5    }
{ mw : 3.5  | }
{ mw : 3.5* | }
{ mw : 3.5  | hello, world  }
{ mw : 3.5  | hello, world* }

更新

一些笔记。

  1. 在您的原始正则表达式中, ?说“0 或 1 个空格字符”。您可能的意思\s*是“0 个或多个空白字符”。
  2. 在您的原始正则表达式中,请注意(.0|.5)实际匹配A0and B5
  3. 您可能需要修改我的正则表达式以重新合并您正在使用的任何内容[\p{P}]?
  4. 看起来您走在正确的轨道上,但您可能使某些事情过于复杂,并且很可能您的空格表达式有些时髦的东西弄乱了您的正则表达式。我鼓励使用我上面链接的工具regexpal.com,逐个测试你的正则表达式,看看哪里没有按预期工作。

更新 2

高度怀疑您是否能够添加标志,但该x标志会大大缩短此正则表达式:

\{(\w+):([3-8]\.[05])(\|[^|*\n]*)*(\|[^|*\n]*\*)(\|[^|*\n]*)*\}
于 2012-07-09T14:39:34.677 回答