如果字符串是Java中的正确格式,如何验证它

J. *_*erd 4 java validation

我目前正在用Java编写验证方法,以检查字符串是否为几种不同的格式之一,以便更改为日期.

我希望它接受的格式如下:MM/DD/YY,M/DD/YY,MM/D/YY和M/D/YY.

我正在测试第一种格式,每次它告诉我即使我进入有效日期它也无效.

这是我当前的代码:

public class IsDateFormatValid
{
   public boolean isValid(String date)
   {
      boolean result = true;
      if(date.length()>8||date.length()<6)
      {
         result= false;
      }
      if(date.length()==8)
      {
         if((Character.toString(date.charAt(2))!= "/")||(Character.toString(date.charAt(5))!="/"))
         {
            result=false;
         }   
      }
      if(date.length()==7)
      {
         if((Character.toString(date.charAt(2))!="/"&&Character.toString(date.charAt(1))!="/") ||(Character.toString(date.charAt(3))!="/"&&Character.toString(date.charAt(4))!= "/"))
         {
            result=false;
         }   
      }

      return result;   
   }
}   
Run Code Online (Sandbox Code Playgroud)

我仍然需要为最后一个格式案例添加条件.我做了一个调试方法,看到总是返回false的部分是说:if((Character.toString(date.charAt(2))!="/")||(Character.toString(date.charAt) (5))!= "/"))

这个问题的主要观点是尝试针对多种格式进行检查,而不仅仅是单一格式,这里的大多数其他问题都是如此.

pau*_*sm4 7

您可能希望迭代可能的格式,如下所示:

例:

private static String[] date_formats = {
        "yyyy-MM-dd",
        "yyyy/MM/dd",
        "dd/MM/yyyy",
        "dd-MM-yyyy",
        "yyyy MMM dd",
        "yyyy dd MMM",
        "dd MMM yyyy",
        "dd MMM yyyy"
};

/**
 * A brute-force workaround for Java's failure to accept "any arbitrary date format"
 */
public static Date tryDifferentFormats (String sDate) {
    Date myDate = null;
    for (String formatString : date_formats) {
        try {
            SimpleDateFormat format = new SimpleDateFormat(formatString);
            format.setLenient(false);
            myDate = format.parse(sDate);
            break;
        }
        catch (ParseException e) {
            // System.out.println("  fmt: " + formatString + ": FAIL");
        }
    }
    return myDate;
}
Run Code Online (Sandbox Code Playgroud)


Gho*_*ica 6

一种可能很昂贵的简单方法; 但不知何故反对良好做法是这样的:

  1. 创建Formatter对象列表(每个允许的模式一个).
  2. 迭代该列表; 并尝试使用每个格式化程序解析日期字符串(lenient设置为false!).如果你得到一个不抛出异常,你知道传入的字符串符合有效的格式.

对于格式解析,您可以查看此问题.

正如彼得指出的那样,这个解决方案不是线程安全的.所以你需要研究那个问题来解决这个问题.

另一方面,当像paulsm4那样做的时候; 你避免了线程问题...但不幸的是,你正在创建很多格式化程序对象; 之后你立即扔掉了.谈论浪费CPU周期并在那里创建"内存垃圾".

备选案文2; 较少"昂贵"是提出一个(或多个)几个正则表达式,它们匹配给定格式的字符串.但当然,这并不像苏珊娜所建议的那么容易; 如你所知,你真的想要拒绝像"55/66/77"这样的字符串,它完全匹配一个简单的正则表达式,它只检查"两位数两个数字两位数两个数字".

所以,是的,选项1很昂贵; 所以这里的问题是:你的验证应该有多好?你想拒绝语法上"正确"的日期,但是"语义上"错误,比如"02/29/15"(2015年不是闰年!)?!

更新:考虑到这一点,一个很好的解决方案如下:

  1. 创建一个Map<Regex, String>值,该值是一个可以用作"格式化程序输入"的字符串; 相应的键是一个"匹配"该格式的正则表达式
  2. 迭代地图键
  3. 如果没有关键匹配:完成; 您知道您的输入格式未知/无效
  4. 如果键匹配:获取该键的映射值并使用它来创建非宽松格式化程序对象.现在您可以检查格式化程序是否可以解析您的输入.如果是这样:输入是您的一种格式的有效日期.