java中最容易犯错的特殊字符

问题背景

能准确说出下面的java 执行完毕后会打印出什么?

        System.out.println(
                String.class.getName()+ ".class");
        System.out.println(
                String.class.getName().
                replaceAll(".","/") + ".class");

相信对于第一行,大部分人不会犯错,打印

java.lang.String.class

我们想使用/去分割类的包,期待打印的结果为

java/lang/String/class

真实返回的结果是这个样子的:

////////////////.class

为什么会这样呢

 原因

  问题在于String.replaceAll 接受了一个正则表达式作为它的第一个参数,而并

非接受了一个字符序列字面常量。(正则表达式已经被添加到了Java 平台的1.4

版本中。)正则表达式“.”可以匹配任何单个的字符,因此,类名中的每一个

字符都被替换成了一个斜杠,进而产生了我们看到的输出。

解决方式

方式一:使用转义字符

        System.out.println(
                String.class.getName().
                replaceAll("\\.","/") + ".class");    

打印结果

java/lang/String.class

是不是有点不懂,为什么会有两个?

第一个"\"代表的是引用(正则表达式中的Quotation),第二个代码"\"转义

Quotation \	Nothing, but quotes the following character \Q	Nothing, but quotes all characters until \E \E	Nothing, but ends quoting started by \Q

方式二 使用Quotation

        System.out.println(
                String.class.getName().
                replaceAll("\\Q.\\E","/") + ".class");    

结果也是

java/lang/String.class

也可以使用

        System.out.println(
                String.class.getName().
                replaceAll(Pattern.quote("."),"/") + ".class");    

其内部实现也是使用Quotation

 /**
 * Returns a literal pattern <code>String</code> for the specified
 * <code>String</code>.
 *
 * <p>This method produces a <code>String</code> that can be used to
 * create a <code>Pattern</code> that would match the string
 * <code>s</code> as if it were a literal pattern.</p> Metacharacters
 * or escape sequences in the input sequence will be given no special
 * meaning.
 *
 * @param s The string to be literalized
 * @return A literal string replacement
 * @since 1.5
 */
 public static String quote(String s) {
 int slashEIndex = s.indexOf("\\E");
 if (slashEIndex == -1)
 return "\\Q" + s + "\\E";
 StringBuilder sb = new StringBuilder(s.length() * 2);
 sb.append("\\Q");
 slashEIndex = 0;
 int current = 0;
 while ((slashEIndex = s.indexOf("\\E", current)) != -1) {
 sb.append(s.substring(current, slashEIndex));
 current = slashEIndex + 2;
 sb.append("\\E\\\\E\\Q");
 }
 sb.append(s.substring(current, s.length()));
 sb.append("\\E");
 return sb.toString();
 }

常见的特殊字符有:

EscapeSequence:\ b (backspace BS, Unicode \\u0008)\ t (horizontal tab HT, Unicode \\u0009)\ n (linefeed LF, Unicode \\u000a)\ f (form feed FF, Unicode \\u000c)\ r (carriage return CR, Unicode \\u000d)\ " (double quote ", Unicode \\u0022)\ ‘ (single quote ‘, Unicode \\u0027)\ \ (backslash \, Unicode \\u005c)OctalEscape (octal value, Unicode \\u0000 to \\u00ff)

还有

Twelve tokens, formed from ASCII characters, are the separators (punctuators).

( ) { } [ ] ; , . ... @ ::

也可以使用下面的方法进行判断

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CheckSpecialCharacterString {

 /**
 * Check whether the each character of String is special character or not using java
 * @author www.instanceofjava.com
 */

public static void main(String[] args) {
String Str="Java String interview questions*$%";

String specialCharacters=" !#$%&‘()*+,-./:;<=>[email protected][]^_`{|}";

for (int i = 0; i < Str.length(); i++) {

 if (specialCharacters.contains(Character.toString(Str.charAt(i))))
 {

 System.out.println(Str.charAt(i)+": is a special character");
 }
 }

}

}

更详细的资料可以参考官方文档【3】

参考资料:

【1】java解惑

【2】https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

【3】https://docs.oracle.com/javase/specs/jls/se12/html/jls-3.html#jls-3.10.6

【4】http://www.instanceofjava.com/2017/05/how-to-check-if-character-is-special.html

原文地址:https://www.cnblogs.com/davidwang456/p/11511209.html

时间: 2024-08-30 04:25:12

java中最容易犯错的特殊字符的相关文章

Java中List.remove报错UnsupportedOperationException

Java中List.remove(removeRange,clear类似) 报出 UnsupportedOperationException 的错误.原来该List是一个AbstractList,不支持增删改操作. 一般情况下我们会使用 LinkedList 和 ArrayList ,什么情况下出现 AbstractList 呢?通过 ArrayList.asList() 函数得到的 List 就是 AbstractList.该AbstractList只是简单地在已有的元素数组上套了一层List

java中的@Override报错解决

问题: 有时候在java的Eclipse工程中会遇到@Override报错,把@Override去掉就好了,可是有时候@Overvide太多,不能从根本上解决问题. 分析: 这是jdk版本之间区别的问题: 在Jdk1.5中@Override就已经有了,但是对接口的实现是不支持的,所以报错. 在Jdk1.6以后无论是对父类的继承还是对接口的实现都支持了 解决:首先确保机器上已经安装了Jdk1.6的版本 然后,选择eclipse菜单Windows->Preferences-->java->C

java中自己常犯的错误汇总

1package debug; 2 3/* 4 1.定义一个公共的动物类,包含名字.年龄.颜色和吃饭东西方法 5 2.定义一个猫类,继承动物类,同时拥有玩游戏的本领 6 3.定义一个狗类,继承动物类,同时拥有看门的本领 7/ 8 9class Animal{10private String name;11privateint age;12private String color;1314public Animal() {1516 }1718publicAnimal(String name,int

java中mysql查询报错java.sql.SQLException: Before start of result set

异常:java.sql.SQLException: Before start of result set 解决方法:使用rs.getString();前一定要加上rs.next(); sm = conn.createStatement(); ResultSet rs = null; String sql_max = "SELECT id FROM a WHERE name= '" + name + "' ORDER BY online_time DESC LIMIT 1&qu

JAVA中Long与Integer比较容易犯的错误

今天使用findbugs扫描项目后发现很多高危漏洞,其中非常常见的一个是比较两个Long或Integer时直接使用的==来比较. 其实这样是错误的. 因为Long与Ineger都是包装类型,是对象.  而不是普通类型long与int , 所以它们在比较时必须都应该用equals,或者先使用longValue()或intValue()方法来得到他们的基本类型的值然后使用==比较也是可以的. 但是有一种特殊情况, 其实Long与Integer都将 -128~127 这些对象缓存了.  可以看看Lon

多线程AsyncTask中使用Jsoup 报错Caused by: java.lang.NoClassDefFoundError: org.jsoup.Jsoup

代码如下,在多线程AsyncTask类中的doInBackground调用Jsoup protected String doInBackground(String... params) { // TODO Auto-generated method stub Log.i(TAG, "doInBackground(Params... params) called"); try { Document doc=Jsoup.connect(params[0]).get(); Elements

JAVA 犯错汇总

ResultSet-->next() //伪代码 ResultSet rs = null; rs1 = stmt.executeQuery(); //if(!rs.next()){ //这里就是坑我代码 // return false; //} while(rs.next()) { //rs.next()这个方法坑了我,让我总是得不到第一条数据 执行一次,往下走一回,我靠,不带这么坑的 } JAVA 犯错汇总

JS 和 Java 中URL特殊字符编码方式

前几天遇到url特殊字符编码的问题,在这里整理一下: JavaScript 1.  编码 escape(String) 其中某些字符被替换成了十六进制的转义序列. 解码 unescape(String) 该函数的工作原理是这样的:通过找到形式为 %xx 和 %uxxxx 的字符序列(x 表示十六进制的数字),用 Unicode 字符 \u00xx 和 \uxxxx 替换这样的字符序列进行解码. *注释:ECMAScript v3 反对使用该方法,应用使用 decodeURI() 和 decode

JAVA中引用com.sun.awt.AWTUtilities时报错

JAVA中引用com.sun.awt.AWTUtilities时报错的解决办法[转] 在Eclipse中设置如下就可以了: When using com.sun.awt.AWTUtilities, Eclipse gives a error: - Access restriction: The method setWindowOpacity(Window, float) from the type AWTUtilities is not accessible due to restriction