如何去除字符串中的 "\n" ?

开发 前端
我最近负责的工作是设计一个 SQL 解析引擎。简单来说,就是将一个 SQL 表达式字符串,解析为一颗对象树,从而执行查询等一系列操作。

[[387047]]

本文转载自微信公众号「程序员鱼皮」,作者 鱼皮。转载本文请联系程序员鱼皮公众号。  

 大家好,我是鱼皮,今天分享一个小知识。

我最近负责的工作是设计一个 SQL 解析引擎。简单来说,就是将一个 SQL 表达式字符串,解析为一颗对象树,从而执行查询等一系列操作。

SQL 解析原理

在最开始,我就遇到了一个很头疼的问题,用户编写的 SQL 语句可能非常不标准!

理想的 SQL 语句,缩进很规范,没有多余的字符:

  1. select * from user

而现实往往是这样的:

  1. select * \n 
  2. rom   user

上述语句不仅缩进、换行很随意,还多了很多无意义的字符串,比如 "\n" !

因此,想要设计一个通用性强的 SQL 解析引擎,首先要对字符串进行 预处理,将输入的 SQL 语句标准化。比如去除回车、换行、冗余的空格和特殊字符等。

那问题来了,如何去除字符串中的所有 "\n" 呢?注意,这里的 "\n" 并不是换行符,而是由字符 '\' 和字符 'n' 组成的字符串!

  1. # 转换前 
  2. select * \n  
  3. from user
  4.  
  5. # 转换后 
  6. select * from user

首先我想到了两种思路:

  • 用循环语句顺序扫描每个字符,通过当前字符和下一个字符判断是否为 "\n",再移除。
  • 直接用 Java 语言提供的 replaceAll 方法,传入一个正则表达式,直接将完整字符串中所有匹配正则的子串替换为空串。

我这里选择后者,直接用现成的方法会比较方便,而且借助强大的正则表达式,可以同时替换掉多个冗余字符。

Java 正则表达式定义:

  1. /* 
  2.  * 全部替换 
  3.  * regex 正则表达式 
  4.  * replacement 要替换成的新串 
  5.  */ 
  6. public String replaceAll(String regex, String replacement) { 
  7.   return Pattern.compile(regex).matcher(this).replaceAll(replacement); 

刚开始我想的太简单了,直接编写出如下代码:

  1. str.replaceAll("\n"""); 

结果,并不能顺利地替换掉字符串中的 "\n",仅仅是把换行符去掉了!

用单个反斜杠的结果

原因很简单,在 Java 字符常量中,反斜杠(\)是一个特殊的字符,被称为 转义字符,它的作用是用来转义后面一个字符,本身不具有实际意义!

因此,不能用下面这种方式直接输出反斜杠:

报错

如果想要单独输出一个反斜杠,需要再加上一个反斜杠转义:

无报错

同理,想要输出一个 "\n" 字符串,代码要这么写:

  1. System.out.println("\\n"

那不妨试试这个正则表达式:

  1. str.replaceAll("\\n"""); 

结果出乎意料,竟然和只用一个反斜杠时的效果一样!仅仅是移除了换行符。

用两个反斜杠的效果

其实,正确的答案应该是使用 四个反斜杠,因为反斜杠在 Java 和正则表达式中都是转义字符!

其中,第一个斜杠是转义符,第二个斜杠是斜杠本身,第三个斜杠又是转义符,第四个斜杠是斜杠本身。

在 Java 中,输出 "\n" 字符串需要两个反斜杠和一个 'n',在 Java 的正则表达式中,要给这两个反斜杠分别再分配一个反斜杠进行转义,才能生效。

总而言之,记住一句话:Java 正则表达式中,匹配一个反斜杠要用四个反斜杠!

 

责任编辑:武晓燕 来源: 程序员鱼皮
相关推荐

2010-06-28 15:18:51

SQL Server

2022-11-25 07:53:26

bash脚本字符串

2022-12-15 16:23:32

JavaScrip字符串开发

2021-01-09 23:11:33

SQL数据库字母

2017-12-11 13:50:17

LinuxBash子字符串

2020-09-03 10:13:49

JavaScript字符串pad

2011-07-11 16:00:22

字符串拼接

2011-06-08 15:45:41

字符串JAVA

2021-09-07 09:23:07

C++字符串算法

2009-02-24 15:39:27

字符串比较函数函数

2010-08-12 10:26:12

FlexXML

2010-09-06 17:30:46

SQL函数

2021-09-10 08:18:31

Go语言字符串

2010-07-13 09:20:38

SQL Server

2015-06-09 14:43:36

javascript操作字符串

2021-04-15 00:16:18

JavaString字符串

2023-08-14 16:30:46

2010-11-25 15:59:33

字符串.NET

2012-01-11 09:15:45

Objective-C

2019-12-17 15:49:44

Java语言字符串
点赞
收藏

51CTO技术栈公众号