Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中拆分字符串以匹配列表中的日期格式_Java_List_Date_Java 8_Java Stream - Fatal编程技术网

在Java中拆分字符串以匹配列表中的日期格式

在Java中拆分字符串以匹配列表中的日期格式,java,list,date,java-8,java-stream,Java,List,Date,Java 8,Java Stream,我有一个要写入CSV文件的字符串列表。列表元素有这样一个字符串 List<String> list1 = new ArrayList<String>(); list1.add("one, Aug 21, 2018 11:08:51 PDT, last"); list1.add("two, newlast, Aug 22, 2018 11:08:52 PDT"); 我能够得到输出 "Aug 21, 2018 11:08:51 PDT" "Aug 22, 2018 11:0

我有一个要写入CSV文件的字符串列表。列表元素有这样一个字符串

List<String> list1 = new ArrayList<String>();
list1.add("one, Aug 21, 2018 11:08:51 PDT, last");
list1.add("two, newlast, Aug 22, 2018 11:08:52 PDT");
我能够得到输出

"Aug 21, 2018 11:08:51 PDT"
"Aug 22, 2018 11:08:52 PDT"

有没有更好的方法来实现这一点,而不必拆分为aarray并对其进行迭代。

输出时,将日期用引号括起来。CSV就是这样逃过他们的

要解析输入,请使用正则表达式。这个将读取每个日期或单词,并使用逗号分隔符

(\w{3} \d{1,2}, \d{4})|(\w+),?
你可以用更多的括号来详细说明你的日期。如果第一个表达式匹配,则为日期。我将留给OP订购最终CSV

这里是用于POC的Javascript中的正则表达式。我知道问题是Java,但正则表达式是一样的

//读单词或日期,后跟逗号 常数rx=/\w{3}\d{1,2}\d{4}\w+,?/g 常量输入=['1,1999年8月2日,2','3,4,2000年8月3日','2010年8月3日,5,6'] 设csv2= input.forEachit=>{ 让零件=[] 设m2=rx.execit 而m2{ 零件.pushm2[1]| | m2[2] m2=rx.execit } csv2+=parts.mapit=>'+it+'.join','+'\n' } console.logcsv2我建议您使用提取日期:

^(.*?)(\w{3} \d{1,2}, \d{4} \d{2}:\d{2}:\d{2} PDT)(.*?)$
和Stream::map来提取日期并尝试解析它。不要忘记过滤空值,因为它们没有通过解析

SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss Z", Locale.ENGLISH);
list1.stream()
     .map(s -> { 
         try {
             return sdf.parse(s.replaceAll("^(.*?)(\\w{3} \\d{1,2}, \\d{4} \\d{2}:\\d{2}:\\d{2} PDT)(.*?)$", "$2")));
         } catch (ParseException e) {} return null; })
     .filter(Objects::nonNull)
     .forEach(System.out::println);
我建议您将try-catch和Regex-extracting打包到一个单独的方法中

static SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss Z", Locale.ENGLISH);

static Date validate(String date) {
    String s = date.replaceAll("^(.*?)(\\w{3} \\d{1,2}, \\d{4} \\d{2}:\\d{2}:\\d{2} PDT)(.*?)$", "$2");
    try {
        return sdf.parse(s);
    } catch (ParseException e) { }
    return null;
}
。。。这大大简化了流程:

list1.stream()
     .map(Main::validate)
     .filter(Objects::nonNull)
     .forEach(System.out::println);

您可以利用普通的日期解析器尝试使用解析位置对每个索引进行解析,并查看其成功之处

现在我试图忽略旧的api,这里有一个新api的简单演示:

public static void main(String[] args) {
    List<String> inputs = Arrays.asList(
        "Aug 21, 2018 11:08:51 PDT",
        "one, Aug 21, 2018 11:08:51 PDT, last",
        "two, newlast, Aug 22, 2018 11:08:52 PDT"
        );
    String formatPattern = "MMM dd, yyyy HH:mm:ss zzz";
    DateTimeFormatter pattern = DateTimeFormatter.ofPattern(formatPattern, Locale.US);

    for(String input : inputs) {
        System.out.println("Processing " + input);

        int[] matchStartEnd = null;
        TemporalAccessor temp = null;

        // check all possible offsets i in the input string
        for(int i = 0, n = input.length() - formatPattern.length(); i <= n; i++) {
            try {
                ParsePosition pt = new ParsePosition(i);
                temp = pattern.parse(input, pt); 
                matchStartEnd = new int[] { i, pt.getIndex() };
                break;
            }
            catch(DateTimeParseException e) {
                // ignore this
            }
        }
        if(matchStartEnd != null) {
            System.out.println("  Found match at indexes " + matchStartEnd[0] + " to " + matchStartEnd[1]);
            System.out.println("  temporal accessor is " + temp);
        }
        else {
            System.out.println("  No match");
        }
    }
}

听起来你需要把日期用引号括起来。因为date中有逗号。pst只是一个提示:如果您有类似的嵌套If语句,请将它们全部合并到一个If中。更易于阅读。可能的副本请查看各种CSV库,例如Apache Commons CSV,这将使读取和写入带有转义值的CSV文件(即引用日期)更加容易。对于不明确的输入格式,您几乎无法做到100%正确。
public static void main(String[] args) {
    List<String> inputs = Arrays.asList(
        "Aug 21, 2018 11:08:51 PDT",
        "one, Aug 21, 2018 11:08:51 PDT, last",
        "two, newlast, Aug 22, 2018 11:08:52 PDT"
        );
    String formatPattern = "MMM dd, yyyy HH:mm:ss zzz";
    DateTimeFormatter pattern = DateTimeFormatter.ofPattern(formatPattern, Locale.US);

    for(String input : inputs) {
        System.out.println("Processing " + input);

        int[] matchStartEnd = null;
        TemporalAccessor temp = null;

        // check all possible offsets i in the input string
        for(int i = 0, n = input.length() - formatPattern.length(); i <= n; i++) {
            try {
                ParsePosition pt = new ParsePosition(i);
                temp = pattern.parse(input, pt); 
                matchStartEnd = new int[] { i, pt.getIndex() };
                break;
            }
            catch(DateTimeParseException e) {
                // ignore this
            }
        }
        if(matchStartEnd != null) {
            System.out.println("  Found match at indexes " + matchStartEnd[0] + " to " + matchStartEnd[1]);
            System.out.println("  temporal accessor is " + temp);
        }
        else {
            System.out.println("  No match");
        }
    }
}