十八、字符串(4)

news2024/9/24 17:16:45

本章概要

  • 扫描输入
    • Scanner 分隔符
    • 用正则表达式扫描
  • StringTokenizer 类

扫描输入

到目前为止,从文件或标准输入读取数据还是一件相当痛苦的事情。一般的解决办法就是读入一行文本,对其进行分词,然后使用 IntegerDouble 等类的各种解析方法来解析数据:

import java.io.*;

public class SimpleRead {
    public static BufferedReader input =
            new BufferedReader(new StringReader(
                    "Sir Robin of Camelot\n22 1.61803"));

    public static void main(String[] args) {
        try {
            System.out.println("What is your name?");
            String name = input.readLine();
            System.out.println(name);
            System.out.println("How old are you? " +
                    "What is your favorite double?");
            System.out.println("(input: <age> <double>)");
            String numbers = input.readLine();
            System.out.println(numbers);
            String[] numArray = numbers.split(" ");
            int age = Integer.parseInt(numArray[0]);
            double favorite = Double.parseDouble(numArray[1]);
            System.out.format("Hi %s.%n", name);
            System.out.format("In 5 years you will be %d.%n", age + 5);
            System.out.format("My favorite double is %f.", favorite / 2);
        } catch (IOException e) {
            System.err.println("I/O exception");
        }
    }
}

在这里插入图片描述

input 字段使用的类来自 java.ioStringReaderString 转化为可读的流对象,然后用这个对象来构造 BufferedReader 对象,因为我们要使用 BufferedReaderreadLine() 方法。最终,我们可以使用 input 对象一次读取一行文本,就像从控制台读入标准输入一样。

readLine() 方法将一行输入转为 String 对象。如果每一行数据正好对应一个输入值,那这个方法也还可行。但是,如果两个输入值在同一行中,事情就不好办了,我们必须分解这个行,才能分别解析所需的输入值。在这个例子中,分解的操作发生在创建 numArray时。

终于,Java SE5 新增了 Scanner 类,它可以大大减轻扫描输入的工作负担:

import java.util.*;

public class BetterRead {
    public static void main(String[] args) {
        Scanner stdin = new Scanner(SimpleRead.input);
        System.out.println("What is your name?");
        String name = stdin.nextLine();
        System.out.println(name);
        System.out.println(
                "How old are you? What is your favorite double?");
        System.out.println("(input: <age> <double>)");
        int age = stdin.nextInt();
        double favorite = stdin.nextDouble();
        System.out.println(age);
        System.out.println(favorite);
        System.out.format("Hi %s.%n", name);
        System.out.format("In 5 years you will be %d.%n",
                age + 5);
        System.out.format("My favorite double is %f.",
                favorite / 2);
    }
}

在这里插入图片描述

Scanner 的构造器可以接收任意类型的输入对象,包括 FileInputStreamString 或者像此例中的Readable 实现类。Readable 是 Java SE5 中新加入的一个接口,表示“具有 read() 方法的某种东西”。上一个例子中的 BufferedReader 也归于这一类。

有了 Scanner,所有的输入、分词、以及解析的操作都隐藏在不同类型的 next 方法中。普通的 next() 方法返回下一个 String。所有的基本类型(除 char 之外)都有对应的 next 方法,包括 BigDecimalBigInteger。所有的 next 方法,只有在找到一个完整的分词之后才会返回。Scanner 还有相应的 hasNext 方法,用以判断下一个输入分词是否是所需的类型,如果是则返回 true

BetterRead.java 中没有用 try 区块捕获IOException。因为,Scanner 有一个假设,在输入结束时会抛出 IOException,所以 Scanner 会把 IOException 吞掉。不过,通过 ioException() 方法,你可以找到最近发生的异常,因此,你可以在必要时检查它。

Scanner 分隔符

默认情况下,Scanner 根据空白字符对输入进行分词,但是你可以用正则表达式指定自己所需的分隔符:

import java.util.*;

public class ScannerDelimiter {
    public static void main(String[] args) {
        Scanner scanner = new Scanner("12, 42, 78, 99, 42");
        scanner.useDelimiter("\\s*,\\s*");
        while (scanner.hasNextInt()) {
            System.out.println(scanner.nextInt());
        }
    }
}

在这里插入图片描述

这个例子使用逗号(包括逗号前后任意的空白字符)作为分隔符,同样的技术也可以用来读取逗号分隔的文件。我们可以用 useDelimiter() 来设置分隔符,同时,还有一个 delimiter() 方法,用来返回当前正在作为分隔符使用的 Pattern 对象。

用正则表达式扫描

除了能够扫描基本类型之外,你还可以使用自定义的正则表达式进行扫描,这在扫描复杂数据时非常有用。下面的例子将扫描一个防火墙日志文件中的威胁数据:

import java.util.regex.*;
import java.util.*;

public class ThreatAnalyzer {
    static String threatData =
            "58.27.82.161@08/10/2015\n" +
                    "204.45.234.40@08/11/2015\n" +
                    "58.27.82.161@08/11/2015\n" +
                    "58.27.82.161@08/12/2015\n" +
                    "58.27.82.161@08/12/2015\n" +
                    "[Next log section with different data format]";

    public static void main(String[] args) {
        Scanner scanner = new Scanner(threatData);
        String pattern = "(\\d+[.]\\d+[.]\\d+[.]\\d+)@" +
                "(\\d{2}/\\d{2}/\\d{4})";
        while (scanner.hasNext(pattern)) {
            scanner.next(pattern);
            MatchResult match = scanner.match();
            String ip = match.group(1);
            String date = match.group(2);
            System.out.format(
                    "Threat on %s from %s%n", date, ip);
        }
    }
}

在这里插入图片描述

next() 方法配合指定的正则表达式使用时,将找到下一个匹配该模式的输入部分,调用 match() 方法就可以获得匹配的结果。如上所示,它的工作方式与之前看到的正则表达式匹配相似。

在配合正则表达式使用扫描时,有一点需要注意:它仅仅针对下一个输入分词进行匹配,如果你的正则表达式中含有分隔符,那永远不可能匹配成功。

StringTokenizer类

在 Java 引入正则表达式(J2SE1.4)和 Scanner 类(Java SE5)之前,分割字符串的唯一方法是使用 StringTokenizer 来分词。不过,现在有了正则表达式和 Scanner,我们可以使用更加简单、更加简洁的方式来完成同样的工作了。下面的例子中,我们将 StringTokenizer 与另外两种技术简单地做了一个比较:

import java.util.*;

public class ReplacingStringTokenizer {
    public static void main(String[] args) {
        String input = "But I'm not dead yet! I feel happy!";
        StringTokenizer stoke = new StringTokenizer(input);
        while (stoke.hasMoreElements()) {
            System.out.print(stoke.nextToken() + " ");
        }
        System.out.println();
        System.out.println(Arrays.toString(input.split(" ")));
        Scanner scanner = new Scanner(input);
        while (scanner.hasNext()) {
            System.out.print(scanner.next() + " ");
        }
    }
} 

使用正则表达式或 Scanner 对象,我们能够以更加复杂的模式来分割一个字符串,而这对于 StringTokenizer 来说就很困难了。基本上,我们可以放心地说,StringTokenizer 已经可以废弃不用了。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1134179.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java】电子病历编辑器源码(云端SaaS服务)

电子病历编辑器极具灵活性&#xff0c;它既可嵌入到医院HIS系统中&#xff0c;作为内置编辑工具供多个模块使用&#xff0c;也可以独立拿出来&#xff0c;与第三方业务厂商展开合作&#xff0c;为他们提供病历书写功能&#xff0c;充分发挥编辑器的功能。 电子病历基于云端SaaS…

机器学习之查准率、查全率与F1

文章目录 查准率&#xff08;Precision&#xff09;&#xff1a;查全率&#xff08;Recall&#xff09;&#xff1a;F1分数&#xff08;F1 Score&#xff09;&#xff1a;实例P-R曲线F1度量python实现 查准率&#xff08;Precision&#xff09;&#xff1a; 定义&#xff1a; …

ORB-SLAM安装过程遇到问题记录整理

一、ORB-SLAM2 1.c error: ‘decay_t’ is not a member of ‘std’ 如下图所示&#xff1a; 解决方法&#xff1a; 修改 ORB_SLAM的 CMAKELIST.txt文件&#xff0c; 将set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdc11") 修改为 set(CMAKE_CXX_STANDARD 14) 2…

R语言的极值统计学、分位数回归、机器学习方法

受到气候变化、温室效应以及人类活动等因素的影响&#xff0c;自然界中极端高温、极端环境污染、大洪水和大暴雨等现象的发生日益频繁&#xff1b;在人类社会中&#xff0c;股市崩溃、金融危机等极端情况也时有发生&#xff1b;今年的新冠疫情就是非常典型的极端现象。研究此类…

2017年亚太杯APMCM数学建模大赛B题喷雾轨迹规划问题求解全过程文档及程序

2017年亚太杯APMCM数学建模大赛 B题 喷雾轨迹规划问题 原题再现 喷釉工艺用喷釉枪或喷釉机在压缩空气下将釉喷入雾中&#xff0c;使釉附着在泥体上。这是陶瓷生产过程中一个容易实现自动化的过程。由于不均匀的釉料在烧制过程中会产生裂纹&#xff0c;导致工件报废&#xff0…

065:mapboxGL在一个图层中随机添加100个标记(marker)

第065个 点击查看专栏目录 本示例的目的是演示如何在vue+mapbox中在一个图层上随机添加100个标记(marker)。要添加多个标记,或者向交互式 Web 或移动地图添加标记,通常必须提供 GeoJSON 格式或矢量切片集的点数据。 您可以在运行之前将数据添加到地图样式,方法是使用 Mapb…

python html(文件/url/html字符串)转pdf

安装库 pip install pdfkit第二步 下载程序wkhtmltopdf https://wkhtmltopdf.org/downloads.html 下载7z压缩包 解压即可, 无需安装 解压后结构应该是这样, 我喜欢放在项目里, 相对路径引用(也可以使用绝对路径, 放其他地方) import pdfkit# 将 wkhtmltopdf.exe程序 路径 p…

STM32F4VGT6-DISCOVERY:uart1驱动

对于这款板子&#xff0c;官方并没有提供串口例程&#xff0c;只能自行添加。 一、PA9/PA10复用成串口1功能不可用 驱动测试代码如下&#xff1a; main.c: #include "main.h" #include <stdio.h>void usart1_init(void) {GPIO_InitTypeDef GPIO_InitStruct…

题目 1120: C语言训练-“水仙花数“问题2python详解)——练气三层后期

✨博主&#xff1a;命运之光 &#x1f984;专栏&#xff1a;算法修炼之练气篇&#xff08;C\C版&#xff09; &#x1f353;专栏&#xff1a;算法修炼之筑基篇&#xff08;C\C版&#xff09; &#x1f352;专栏&#xff1a;算法修炼之练气篇&#xff08;Python版&#xff09; ✨…

基于 nodejs+vue城市轨道交通线路查询系统mysql

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

.NET、VUE利用RSA加密完成登录并且发放JWT令牌设置权限访问

后端生成公钥私钥 使用RSA.ToXmlString(Boolean) 方法生成公钥以及私钥。 RSACryptoServiceProvider rSA new(); string pubKey rSA.ToXmlString(false);//公钥 string priKey rSA.ToXmlString(true);//私钥 后端将生成的公钥发送给前端 创建一个get请求&#xff0c;将…

关于网络安全运营工作与安全建设工作的一些思考

以下内容是个人成长过程中对于网络安全运营工作的理解和思考&#xff0c;希望通过这篇文章帮助大家更好的去做安全运营体系化建设&#xff0c;开始吧&#xff01; 文章目录 一、网络安全运营是什么&#xff1f;二、网络安全运营建设阶段第一阶段&#xff1a;设备限制阶段第二阶…

思维导图软件 ConceptDraw MINDMAP mac中文特色介绍

ConceptDraw MINDMAP mac是一款思维导图绘制软件&#xff0c;它可以帮助用户快速创建各种类型的思维导图&#xff0c;如组织结构图、流程图、概念图和UML图等。该软件具有直观的界面和简单易用的操作方式&#xff0c;使得用户能够轻松地创建复杂的思维导图。此外&#xff0c;它…

【Java集合类面试二十六】、介绍一下ArrayList的数据结构?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;介绍一下ArrayList的数据…

C++ list 模拟实现

目录 1. 基本结构的实现 2. list() 3. void push_back(const T& val) 4. 非 const 迭代器 4.1 基本结构 4.2 构造函数 4.3 T& operator*() 4.4 __list_iterator& operator() 4.5 bool operator!(const __list_iterator& it) 4.6 T* operator->…

douyin ios 六神参数学习记录

玩那么久安卓了&#xff0c;也终于换一换ios终端分析分析&#xff0c;还是熟悉的x-gorgon&#xff0c;x-argus&#xff0c;x-medusa那些参数。 随便抓个抖音 ios版本的接口&#xff1a; 像评论接口&#xff1a; https://api26-normal-hl.amemv.com/aweme/v2/comment/list/?…

Unsatisfied dependency expressed through bean property ‘sqlSessionTemplate‘;

代码没有问题&#xff0c;但是启动运行报错 2023-10-25 16:59:38.165 INFO 228964 --- [ main] c.h.h.HailiaowenanApplication : Starting HailiaowenanApplication on ganluhua with PID 228964 (D:\ganluhua\code\java\hailiao-java\target\classes …

mysql 基础知识

MySQL 是一种关系型数据库&#xff0c;在Java企业级开发中非常常用&#xff0c;因为 MySQL 是开源免费的&#xff0c;并且方便扩展。阿里巴巴数据库系统也大量用到了 MySQL&#xff0c;因此它的稳定性是有保障的。MySQL是开放源代码的&#xff0c;因此任何人都可以在 GPL(Gener…

HarmonyOS鸿蒙原生应用开发设计- 华为分享图标

HarmonyOS设计文档中&#xff0c;为大家提供了独特的华为分享图标&#xff0c;开发者可以根据需要直接引用。 开发者直接使用官方提供的华为分享图标内容&#xff0c;既可以符合HarmonyOS原生应用的开发上架运营规范&#xff0c;又可以防止使用别人的内容产生的侵权意外情况等&…

大型应用的架构演进--spring家族在其中的作用

01 大型应用的架构演进 带来的挑战&#xff1a; 运维与监控 分布式带来的复杂性 接口的调整成本 测试成本 依赖管理成本 02 Spring家族 在我看来&#xff0c;springboot的3大特点(我常用的)&#xff1a;内置的web容器&#xff1b;开箱即用的starter模版&#xff1b;自动配置&…