深入理解Java中的转义字符

news2024/11/14 15:02:17

最近在学习《两周自制脚本语言》这本书,在词法分析的一些复杂的正则中用到了大量的转义字符’\',比如正则字符串中包含了这个部分\\\\\"你知道它是匹配什么的么?

反斜杠在字符串和正则表达式中都有特殊作用。今天让我们来深入理解一下Java中的转义字符\

先提几个问题:
  1. Java中的字符串中的\n是一个字符还是两个?
  2. Java中代码中的字符串字面量"abc",在存储的时候,字符串内容中有没有双引号?
  3. Pattern pat = Pattern.compile(“\\\\\\\\”); (双引号内有8个反斜杠),请问它可以匹配字符串中的什么内容?非得用8个反斜杠才能表达要匹配的字符串么?6个或4个可不可以?

字符串字面量

字面量两边的双引号是干嘛的

在Java代码中写出来的字符串,叫做字符串字面量,比如String name = "Jack"中的字符串Jack就是字面量形式给出来的,它在编译后的程序中会保存在字符串常量池中。保存的内容仅仅是Jack这个字符串,共4个字符,是没有两边的双引号的。两边的双引号,仅仅是代码中写的,给Java编译器看的,编译器看到代码中出现了双引号,就知道接下来的内容是字符串,所以真正的字符串内容就是Jack这四个字符。想想name.length()不就是4么。

字符串内容中有双引号怎么办

假设我有个字符串内容是"You hurt me", she said.。代码中如果将这个字符串不做处理地用双引号包裹起来就出了问题:

String str = ""You hurt me", she said.";

编译器的眼里,只有两个字符串,第一个是空字符串,第二个是, she said.。因为编译器是通过双引号来判断字符串字面量的起止位置的。

如果你想要在字符串中包含双引号,代码要这么写:

String str = "\"You hurt me\", she said.";

即在字符串内容中的双引号前加上反斜杠作为转义字符,这样编译器读取到\"的时候,就不会认为它是字符串的结束了。

字符串内容中有反斜杠怎么办

假设我们字符串的内容中也有反斜杠,比如The backslash \ is an escape character,我们也需要在反斜杠前加一个反斜杠作为转义字符:

String str = "The backslash \\ is an escape character";
多个连续的反斜杠该怎么解读

那如果字符串的内容包含了\"该怎么写的?比如字符串的内容是The \" inner string literals means a double quote,那就要写成如下的方式:

String str = "The \\\" inner string literals means a double quote";

在字符串字面量中,如果有多个反斜杠连在一起,则奇数位置(1,3,5,7…)上的反斜杠表示转义,和它后边的字符共同决定含义。那么字符串字面量中的\\\"中的第1个反斜杠表示对它后边的反斜杠的转义,第2个反斜杠就不再是转义字符了,它被它前面的转义字符给剥夺了转义的超能力。前两个反斜杠连在一起表示一个反斜杠字符,第3个反斜杠和它后面的双引号一起表示字符串内容中的双引号。

在这里插入图片描述

字符串中多个反斜杠连续起来,只有奇数位置1,3,5,7这些位置上的反斜杠具有转义的超能力,其它位置上的都被它前面的转义字符给剥夺了转义的超能力,仅仅表示反斜杠字符本身了。所以字符串中的\\\\\\\\(8个反斜杠)表示的其实是4个反斜杠字符。这4个反斜杠字符不再具有转义的能力,不会继续转义下去。

在这里插入图片描述
但是,如果这个8个反斜杠的字符串作为正则表达式的话,它的内容是4个反斜杠,这其中奇数位置的反斜杠又有了转义的能力,不过这个转义能力是正则表达式中的转义。 所以8个反斜杠的字符串作为Pattern.compile参数的话,它先是被解读为字符串,然后这个字符串又被当作正则表达式的pattern使用。4个反斜杠在正则表达式中表示的是两个连续的反斜杠。本文后边会讲解正则表达式中的转义。

字符串内容中包含换行怎么办

如果字符串中包含了换行符,那么就需要在字符串中用\n来表示换行,换行符实际上是一个字符,因为换行符是不可打印不可显示的字符,所以你没办法在代码中直接表示它,各种编程语言都规定用\n来表示换行,也就是说在程序的代码中,要用反斜杠和字母n的组合来表示换行,但是实际上它们的组合表示的是一个换行符。

/**
 * 一个字符,才可以用char类型
 */
char c = '\n';
String lineSeparator = "\n";
System.out.println(lineSeparator.length()); // 输出1

正则表达式中的反斜杠

在正则表达式中也有反斜杠\,它也有转义的能力。比如正则表达式中的元字符表示或的关系,如果在它前面加上了反斜杠,就仅仅表示竖线了:

在这里插入图片描述

在这里插入图片描述

也就是说在正则表达式中,反斜杠字符也是有转义的超能力的。

当Java的字符串遇上正则表达式

注意:反斜杠在Java的字符串和正则表达式中都具有转义的作用,如果它们遇到一起就需要分两步骤来解读反斜杠: 第一步将它作为字符串的含义解读出来,第二步将前一步解读出来的字符串作为正则表达式的含义解读出来。

比如我想匹配字符串中的a|b,用正则表达式写的pattern就是a\|b,可是到了java中,就得写成下面的:

// 要多加一个转义,看起来貌似正则表达式本身不太一样似的
Pattern pat = Pattern.compile("a\\|b"); 

而如果正则表达式中要匹配的是反斜杠本身,就更麻烦了,在正则表达式中要用两个反斜杠才能表达反斜杠本身。而要用java的字符串来写正则表达式的pattern,反斜杠的数量还要翻倍,比如:

Pattern pat = Pattern.compile("\\\\"); // 用于匹配字符串中单个反斜杠 

现将代码中的四个反斜杠的字符串字面量解读成有两个反斜杠字符的字符串内容本身,然后将有两个反斜杠的字符串内容作为正则表达式的pattern,那么本来已经归于平凡的反斜杠在正则表达式中又一次具有了转义的能力!

在这里插入图片描述

所以说如果Java中的正则表达式要想匹配字符串中的\",要写成:

//前面4个反斜杠表示一个不具备转义能力的反斜杠字符,
//第5个反斜杠和后边的双引号表示字符串内容中的双引号
Pattern pat = Pattern.compile("\\\\\""); 

为什么Java中的正则会有转义字符满天飞,不好读懂

造成这个现象的原因,就是Java中不支持raw string这种字符串,比如有的编程语言通过三个双引号或者三个单引号来表示raw string,这样在raw string中有双引号之类的就不用再转义一下了。比如Rust中的raw string:

在这里插入图片描述

如果用Rust的正则来匹配字符串中的反斜杠本身,则简单的多:

    //用于匹配字符串中的反斜杠,注意这儿之所以还需要写两个反斜杠,是正则表达式本身就需要两个
	//因为在正则表达式中,反斜杠也具有转义的功能,如果用Java写,则要写4个,多一倍的反斜杠是Java字符串造成的
    let regex = Regex::new(r"\\").unwrap();

英文词汇:

  1. 转义字符: escape character
  2. 反斜杠(\): backslash
  3. 字符串字面量: string literals

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

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

相关文章

如何使用drawio画流程图以及导入导出

画一个基本的流程图 你可以在线使用drawio, 或者drawon创建很多不同类型的图表。 如何使用编辑器,让我们以一个最基本的流程图开始。 流程图,就是让你可视化的描述一个过程或者系统。 图形和很少部分的文字表达就可以让读者很快的理解他们需要什么。 创…

文心大模型走进高校!百度携手吉林大学计算机学院成功举办AI师资培训

随着人工智能技术的快速发展,大模型已经成为了人工智能的主流发展方向,同时也对新时代AI人才的培养带来了新的思考与挑战。为了推动大模型及人工智能相关专业人员的培养,10月20日-22日,百度飞桨携手中国电子学会,吉林大…

@TableLogic 这个注解的作用

TableLogic 是 MyBatis-Plus(一个 MyBatis 的增强工具)提供的一个注解,用于实现逻辑删除功能。 逻辑删除并不是真正从数据库中删除记录,而是通过在数据库表中设置一个标记字段(通常是一个状态字段,如 is_d…

【Linux】部署及发布单机项目及前后端分离的项目

目录 一、讲述 1. 为什么 2. 要求 二、单机项目 1. 本机测试 2. 部署 三、前后端 1. 准备 2. 部署 一、讲述 1. 为什么 实施部署和发布项目的目的是将软件开发的成果转化为可用的产品或服务,以满足用户的需求。以下是实施部署和发布项目的一些重要原因&am…

Proteus仿真--闪烁的LED灯

本文介绍一种基于51单片机实现的LED灯闪烁仿真(完整仿真源文件及代码见文末链接) 本文主要介绍51单片机的LED闪烁仿真设计,仿真文件截图如下: 仿真视频如下: Proteus仿真--闪烁的LED灯 附完整Proteus仿真资料代码资…

NlogPrismWPF

文章目录 Nlog&Prism&WPF日志模块实现原理添加配置注入服务应用测试其他模块怎么调用? Nlog&Prism&WPF 日志模块 介绍了为WPF框架Prism注册Nlog日志服务的方法 实现原理 无论是在WPF或者ASP.NET Core当中, 都可以使用ServiceCollection来做到着…

【软考】10.1 算法特性/时间复杂度/递归/分治/动态规划

《算法》 《时间复杂度》 n 的最高次项 渐进符号 算法复杂度 线性级 O(n):顺序查找对数级 O(logn):对半查找、快速查找、归并算法 《递归》 时间复杂度 《分治法》 《动态规划法》 适用于求全局最优解构建…

MySQL总结 (思维导图,常用)

一、常见的增删改查 二、约束(五种) 三、聚合查询 1、聚合函数 2、group by 和 having 3、联合查询 案例表: drop table if exists classes; create table classes (id int primary key auto_increment,name varchar(20) ); insert into …

CAD2024最新中文版安装教程分享

wx供重浩:创享日记 对话框发送:cad24 获取 AutoCAD是目前计算机辅助设计领域最流行的CAD软件,此软件功能强大、使用方便,在国内外广泛应用于机械、建筑、家居、纺织等诸多行业。CAD制图软件具有良好的用户界面,通过交互…

开发直播商城APP:技术要点和最佳实践

在当今数字时代,直播商城APP正变得越来越受欢迎,成为了吸引消费者和促进销售的强大工具。这篇文章将探讨开发直播商城APP的技术要点和最佳实践,为开发者提供有价值的指导。 第一部分:项目准备 1.1定义项目目标 在开始开发直播商…

中国黑客群体的收入,与国外的黑客调查问卷相比!竟然还有女黑客!

从圈外认知来说,黑客一直被认为是高收入群体,黑客有白帽和黑帽处于黑白两道的黑客会的技术都有些相似,但是却是对立的,白帽做网络安全,修补漏洞。黑帽各种破坏,挖数据,攻击漏洞。 如果你对网络…

网络编程 - IP协议

目录 一,IP协议格式 1.1 拆包组包 1.2 8位生存空间 二,地址管理 2.1 动态分配 IP 2.2 NAT 机制(网络地址转换) 2.3 IPv6 2.4 网段划分 三,路由选择 一,IP协议格式 4位版本:IPv44位首部长…

数据结构和算法(15):排序

快速排序 分治 快速排序与归并排序的分治之间的不同: 归并排序的计算量主要消耗于有序子向量的归并操作,而子向量的划分却几乎不费时间; 快速排序恰好相反,它可以在O(1)时间内,由子问题的解直接得到原问题的解&#…

rust 创建多线程web server

创建一个 http server,处理 http 请求。 创建一个单线程的 web 服务 web server 中主要的两个协议是 http 和 tcp。tcp 是底层协议,http 是构建在 tcp 之上的。 通过std::net库创建一个 tcp 连接的监听对象,监听地址为127.0.0.1:8080. us…

轻松合并多个TXT文本,实现一键文件整理!

亲爱的读者们,您是否曾经需要将多个TXT文本文件合并成一个文件,却苦于无从下手?现在,我们向您介绍一个全新的TXT文本合并工具,让您轻松实现一键文件整理! 首先,在首助编辑高手的主页面板块栏里…

数据库分库分表的原则

目录 1、数据库分库分表是什么 2、为什么要对数据库分库分表 3、何时选择分库分表 4、⭐分库分表遵循的原则 5、分库分表的方式 6、数据存放在表和库中的规则(算法) 7、分库分表的架构模式 8、分库分表的问题 小结 1、数据库分库分表是什么 数…

嵌入式学习笔记(64)指针带来的一些符号的理解

我们写的代码是给编译器看的,代码要想达到你想象的结果,就必需要编译器对你的代码的理解和你自己对代码的理解一样。编译器理解代码就是理解的符号,所以我们要正确理解C语言中的符号,才能像编译器一样思考程序、理解代码。 3.2.1…

如何入门学习黑客技术?如何选择编程语言?如何选择适合黑客的操作系统?

‘ 一 ’ 了解黑客技术的基础知识 学习黑客技术需要对网络安全和计算机系统有一定的了解。可以通过参加安全培训班、阅读专业书籍和学术论文、浏览网络安全博客和论坛等方式获取基础知识。涉及的内容包括网络协议、操作系统原理、计算机网络和编程等。 如果你对网络安全入门…

C语言 每日一题 PTA 10.28 day6

1.求奇数分之一序列前N项和 本题要求编写程序,计算序列 1 1 / 3 1 / 5 ... 的前N项之和。 输入格式 : 输入在一行中给出一个正整数N。 输出格式 : 在一行中按照“sum S”的格式输出部分和的值S,精确到小数点后6位。题目保证计算结果不超过双精度范围…

基于 Python 的豆瓣电影分析、可视化系统,附源码

文章目录 1 简介2 技术栈具体实现1.设计豆瓣电影自动化爬虫程序,自动获取电影数据2.对爬取到的数据进行清洗和预处理,包括多维度数据字段清洗和扩充3.将清洗好的数据存储到MySQL数据库中 4 具体效果图5 推荐阅读 1 简介 基于Python flask 的豆瓣电影分析…