2

我有一种情况,我需要造句并选中某些框和/或在文本输入中输入数字。

盒子就像..

  • 每天
  • 每周
  • 每个月

所以我不确定使用不同的正则表达式对象来搜索不同的情况是否会更好,或者我是否应该尝试制作 1 个大的正则表达式对象然后切换/大小写结果。

以下是字符串可以是什么的一些示例:

  • 每天
  • 每个工作日
  • 每周日、周一、周三
  • 每 3 周的星期日、星期五
  • 每个月的第一个星期日
  • 每 2 个月的第 1 天
  • 每年 1 月 1 日

当涉及到正则表达式时,我可以做得很好,但这不合时宜,我不确定我是否应该使用不同的正则表达式对象或尝试做一个大对象。谢谢你的帮助

看起来 /\w+\s?(\d+?)?\s(\w+)/ 负责“每周”、“每天”、“每月”、“每年”、“每 10 天” , ETC。

4

2 回答 2

3

我认为正则表达式在这里不会对您有太大帮助。他们可能能够进行一些非常简单的匹配,但是您在这里真正看到的是语法解析问题。您可能想阅读旨在表达抽象语法的语言,例如扩展巴科斯-瑙尔形式(EBNF)。这听起来很吓人,但实际上并不难掌握。一旦你能够用一种正式的语言来描述你的语法,解析它就会变得容易得多(至少,你有一个关于什么样的输入是有效的规范)。例如,您的问题可能有以下 EBNF:

expression = "every" time-unit|time-unit-list|composite-time-unit
time-unit = { ordinal } "day" | "weekday"
ordinal = "first" | "second" | "third" | ...

等等。这不是一项微不足道的工作;解析一个英语句子,即使是这样一个相当严格的句子也可能涉及很多。然而,这是一种成熟而严格的方法。

一旦你定义了你的语法,你就可以为它构建一个解析器。这是寻找终端(如“每个”)然后将它们与规则匹配的问题。例如,您可能有如下内容(伪代码):

words = split(/\s*/,lowercase(input))
if( words[0] == "every" ) {
  switch( words[1] ) {
    case "first":
    case "second":
    case "third":
    ...
      parseTimeUnit(words);
      break;
    case "day":
      everyDay = true;
      break; 
    ...
  }
}

根据语法的复杂性,您可能会考虑使用Yacc之类的东西自动生成解析器。

您已经解决了一大堆问题,但解决问题是有益的,祝您好运!

更新:我只建议使用 Yacc,因为它是我所知道的最古老的解析器生成器之一。但是,其中有一百万个,其中很多会为您发出 Javascript。您可以查看Wikipedia 对解析器生成器的比较了解更多信息。

于 2012-08-28T01:03:22.920 回答
0

似乎您要做的是将字符串解析为某种数据结构,并且我认为这不是正则表达式的工作(尽管它可能是解决方案的一部分)。

于 2012-08-28T00:54:14.020 回答