无法解析文本,找到未解析的文本

如何解决无法解析文本,找到未解析的文本

当我传递的文本符合格式时,我无法弄清楚为什么会出现 DateTimeParseException 错误。以下是导致问题的代码:

LocalTime lt = LocalTime.parse(songTime,DateTimeFormatter.ofPattern("k:m:s"));

这就是奇怪的事情。每当我查询用户一段时间(让我们以 00:02:30 为例)时,它就会完全按照我的意愿运行。但是当我使用我的方法(从文本文件中提取时间)时,它给出了错误:

线程“main”中的异常java.time.format.DateTimeParseException: 文本 '00:02:30 ' 无法解析,在索引 8 处找到未解析的文本

我假设的第一件事是,它可能会引入额外的空白或类似的东西。所以为了检查这一点,我在变量的每一侧打印了 3 行并打印了这个:

---00:02:30---

如上所示,没有空格。如果我对 00:02:30 进行硬编码,那么它也能完美运行。然后我遇到了另一件让我烦恼的事情。我的文本文件如下所示:

00:00:00 First
00:02:30 Second

第一次完美通过,但之后的任何人都会导致错误。它们都具有完全相同的格式,两边都没有空格,所以我看不到问题。我检查了关于这个问题的每一个论坛帖子,其中大多数是使用错误格式、错误字符串等的个人。我不确定这里的情况,因为当我对其进行硬编码或查询用户输入时它可以完美运行。

以下是我在格式化程序中选择的每个选项的含义(来自documentation):

k       clock-hour-of-am-pm (1-24)
m       minute-of-hour 
s       second-of-minute

这里是读取文件的方法:

public static ArrayList<Song> scanInSongs () {

ArrayList<Song> songArray = new ArrayList<Song>();

try { 

    BufferedReader reader = new BufferedReader(new FileReader("Description.txt"));
    String line;

    while ((line = reader.readLine()) != null) {
       String key = line.substring(0,line.indexOf(' '));
       System.out.println("Fetched timestamp: "+ key);
       String value = line.substring(line.indexOf(' ') + 1);
       System.out.println("Fetched name: "+ value);

       Song song = new Song(value,"",key);
       songArray.add(song);
    }
} catch (IOException e) {
    System.out.println("File not found,exception: "+ e);
} 

return songArray;

}

歌曲类:

public class Song {
    private String duration = "";
    private String name = "";
    private String timestampFromVideo = "";

    public Song(String name,String timestampFromVideo,String duration) {
        if (name == "") {
            this.name = "";   
        } else {
            this.name = name;
        }
        this.duration = duration;

        this.timestampFromVideo = timestampFromVideo;
    }

    public String getName() {
        return this.name;
    }

    public String getDuration() {
        return this.duration;
    }

    public String getTimestampFromVideo() {
        return this.timestampFromVideo;
    }

    public void setDuration(String duration) {
        this.duration = duration;
    }

}

主要内容:

public static void main(String[] args) {

    ArrayList<Song> songArray = scanInSongs();

    String songTime = songArray.get(0).getDuration();

    LocalTime lt = LocalTime.parse(songTime,DateTimeFormatter.ofPattern("k:m:s"));       
}

最后是文件:

00:00:00 First
00:02:30 Second

提前感谢大家的帮助!

解决方法

您使用了错误的类型

00:02:30 是指 Duration,而不是 LocalTime

您可以将字符串转换为 ISO 8601 format for a Duration,然后将结果字符串解析为 Duration

演示:

import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        System.out.println(parse("00:02:30"));
        System.out.println(parse("00:00:00"));
    }

    static Duration parse(String strDuration) {
        String[] arr = strDuration.split(":");
        Duration duration = Duration.ZERO;
        if (arr.length == 3) {
            strDuration = "PT" + arr[0] + "H" + arr[1] + "M" + arr[2] + "S";
            duration = Duration.parse(strDuration);
        }
        return duration;
    }
}

输出:

PT2M30S
PT0S

ONLINE DEMO

您不需要 DateTimeFormattter 来解析 ISO 8601 格式的时间

现代日期时间 API 基于 ISO 8601,只要日期时间字符串符合 ISO 8601 标准,就不需要明确使用 DateTimeFormatter 对象。

演示:

import java.time.LocalTime;

public class Main {
    public static void main(String[] args) {
        System.out.println(LocalTime.parse("00:02:30"));
        System.out.println(LocalTime.parse("00:00:00"));
    }
}

输出:

00:02:30
00:00

ONLINE DEMO

Trail: Date Time 了解有关现代 Date-Time API 的更多信息。

,

文件中的非打印字符

你的字符串中有一个非打印字符(所以不是空格,因为 strip() 没有帮助)。由于字符串已从文件中读取,因此该字符必须在文件中。

如何检查:

    key.chars().forEach(System.out::println);

如果 key 只是 "00:02:30",这将打印

48
48
58
48
50
58
51
48

我敢打赌你的输出比这多。例如,如果您有:

48
48
58
48
50
58
51
48
8203

在这里我们可以看到在字符串的末尾有一个 unicode 值为 8203(十进制)的字符。这是一个零宽度空间,这就解释了为什么我们在打印字符串时看不到它。 LocalTime.parse() 可以看到它,它解释了您收到的错误消息。

有趣(也许令人失望)对于 anish sharma 在他的回答中建议的 strip 方法来说,零宽度空格不算作空白,这就是为什么那个答案没有解决问题。

好的解决方案是从文件中删除该字符。

另一个改进建议:java.time.Duration

我完全同意 Arvind Kumar Avinash 的回答:您应该在一段时间内使用 Duration 类(如果有一天您遇到超过 24 小时的持续时间,LocalTime 也将不再有效) .并且您应该更进一步地使用 Duration,并在您的模型类中将持续时间保持为 Duration,而不是字符串。就像您将数字保存在 int 变量中而不是字符串中一样(我非常希望)。

public class Song {
    private Duration duration;
    private String name;
    // …

因为你的实例变量总是从构造函数初始化,不要在声明中给它们默认值,那只会混淆。您可以编写一个方便的构造函数来将字符串解析为 Duration,例如:

/** @throws DateTimeParseException if durationString is not in format hh:mm:ss */
public Song(String name,String timestampFromVideo,String durationString) {
    this.name = "";   
    String iso = durationString.replaceFirst(
            "^(\\d{2}):(\\d{2}):(\\d{2})$","PT$1H$2M$3S");
    duration = Duration.parse(iso);

您测试 if 是否为空的 name 语句既错误又多余,所以我忽略了它。您不能使用 == 比较字符串。要测试字符串是否为空,请使用 name.isEmpty() (要求字符串非空,这是从文件中读取的)。由于您无论如何都将空字符串分配给 name,我发现省略检查更简单。

我将持续时间字符串转换为 Duration.parse() 要求的 ISO 8601 格式的方法与 Arvind Kumar Avinash 的答案不同。如果他的方式比较容易理解,一定用它就好了。

额外奖励:如果您希望转换为 ISO 8601 以在秒后省略任何字符,包括零宽度空格,请使用此变体:

    String iso = durationString.replaceFirst(
            "^(\\d{2}):(\\d{2}):(\\d{2}).*$","PT$1H$2M$3S");

我在表示字符串结尾的 .* 之前插入了 $。这匹配可能存在的任何字符,并导致它们不会进入 ISO 8601 字符串。所以现在当文件中有零宽度空格时解析也有效。

此外,如果您使用 Duration 则不相关,Arvind 也是正确的,如果您想解析为 LocalTime,您将不需要 DateTimeFormatter,因为 00:02:30在一天中的某个时间采用 ISO 8601 格式,LocalTime 解析此格式而无需指定格式化程序。最后,Joachim Isaksson 在评论中是正确的,即模式字母 k 对于一天中的小时是不正确的,因为它可以是 0。kclock-hour-of-day (1-24) 。对于一天中的一小时 (00–23),您将需要 HH

链接

,

使用java 9的strip()方法。 假设 songTime 是您从文本文件中读取的字符串,然后使用 songTime.strip()。

strip() 方法删除所有 Unicode 空格以及普通空格

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res