动态正则表达式用于日期时间格式

5

是否有现有解决方案可以根据给定的日期时间格式模式动态创建正则表达式?支持的日期时间格式模式不重要(Joda DateTimeFormatjava.text.SimpleDateTimeFormat或其他)。

以具体的示例为例,对于给定的日期时间格式,例如dd/MM/yyyy hh:mm,它应生成相应的正则表达式以匹配指定格式内的日期时间。

4个回答

3
我猜你的时间格式只能由有限的字母组成。这意味着,“HH”在24小时制下总是代表“小时”,“dd”总是带前导零的日期等等。
由于时间格式是顺序性的,你可以尝试将一个格式字符串“dd/mm/yyyy HH:nn”划分为一个数组["dd", "/", "mm", "/", "yyyy", " ", "HH", ":", "nn"]。然后,通过用"([01][0-9]|2[0-3])"替换"HH"等等,来形成一个模式字符串。把这些模式原子预先构建到一个查找表/数组中。数组中不在查找表中的部分都是文字。请按照相应的正则表达式规则进行转义,并将它们附加到您的模式字符串中。
编辑:对于基于正则表达式的解决方案而言,当你将查找表中所有正则表达式“原子”放入括号中,并跟踪给定格式字符串中的其顺序时,你将能够使用子匹配从匹配中提取所需组件,并将它们馈送到CreateDate函数中,从而完全跳过ParseDate部分。

这个程序运行得还不错,但是它比较偏向英语。"ddd" 可能会被映射到 (mon|tue|wed|thu|fri|sat|sun),但你需要一个与本地相关的映射。当日期格式生成非 ASCII 数字时,情况会变得更糟。请参阅 M.Kaplan 的博客,了解更多关于 i18n 的详细信息。 - MSalters
是的,那正是我需要的。因为找不到已经存在的东西,所以我想做类似的事情。为了解析dateTimeFormat,我使用了jflex。所以如果是“d”,它应该匹配1或2个数字,如果是“ddd”,它应该匹配3个数字等等。然而,我仍然需要改进它以适应国际化。 - hakan
@MSalters。您能提供一下您提到的博客链接吗?谢谢。 - hakan
对于依赖于语言环境的模式,您可以进一步抽象并从您所使用的语言环境日期函数构建查找表。当然需要先了解您所使用的日期语言,但这样做非常简单直接。 - Tomalak
请注意,“dd”代表“两位数字”,可能会产生误报。例如,“99”会匹配成功,但显然不是有效的日期组件,除非它表示“两位数年份”。 - Tomalak
显示剩余2条评论

1
如果您正在寻找基本的日期检查,此代码与此数据匹配。
\b(0?[1-9]|[12][0-9]|3[01])[- /.](0?[1-9]|1[012])[- /.](19|20)?[0-9]{2}\b

10/07/2008  
10.07.2008
1-01/2008
10/07/08    
10.07.2008
1-01/08

通过regexbuddy编写代码


我需要一个针对给定的DateTimeFormat生成正则表达式的工具。我不知道给定语料库中使用的日期格式。因此,用户首先应该提供类似于DDMM hh:mm之类的信息,以便我在文本中找到这些日期值。我已经使用JFlex创建了一个东西。我稍后会在此处发布它。 - hakan

0

SimpleDateFormat 已经通过 parse() 方法实现了这一点。

如果您需要从单个字符串解析多个日期,请使用正则表达式(即使它匹配过于宽松),并在正则表达式找到的所有潜在匹配上使用parse()方法。


只有当给定的文本与模式匹配并返回该字符串的日期对象表示时,它才会解析。如果日期信息在其他文本中的某个位置,则不会解析,例如:“一些文本 12/03/2004 一些文本”。 - hakan
可能是无法判定的。如果文本包含两个日期,例如“在A和B之间”,其中A和B是日期…… - Jason Cohen
好的,那么就会将它们分成两组,就像正则表达式查找一样。 - hakan

0

以下给出的js / jQuery代码是用于动态生成仅针对日期格式的正则表达式,而不是DateTime(开发版本尚未完全测试)。

日期格式应为“D M Y”。

例如:

  • DD-MM-YY
  • DD-MM-YYYY
  • YYYY-MM-DD
  • YYYY-DD-MM
  • MM-DD-YYYY
  • MM-DD-YY
  • DD/MM/YY
  • DD/MM/YYYY
  • YYYY/MM/DD
  • YYYY/DD/MM
  • MM/DD/YYYY
  • MM/DD/YY

或其他使用“D M Y”字符创建的格式:

var dateFormat = "DD-MM-YYYY";
var order = [];
    var position = {"D":dateFormat.search('D'),"M":dateFormat.search('M'),"Y":dateFormat.search('Y')};
    var count = {"D":dateFormat.split("D").length - 1,"M":dateFormat.split("M").length - 1,"Y":dateFormat.split("Y").length - 1};
    var seprator ='';
    for(var i=0; i<dateFormat.length; i++){
  if(["Y","M","D"].indexOf(dateFormat.charAt(i))<0){
    seprator = dateFormat.charAt(i);
  }else{
    if(order.indexOf(dateFormat.charAt(i)) <0 ){
        order.push(dateFormat.charAt(i));
    }
  }
    }
    var regEx  = "^";
    $(order).each(function(ok,ov){
    regEx  += '(\d{'+count[ov]+'})'+seprator;
    });
    regEx = regEx.substr(0,(regEx.length)-1);
  regEx  +="$";
  var re = new RegExp(regEx);
  console.log(re);

注意:月份/日期没有验证检查 例如,月份应为01-12或日期应为01-31


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