1.前言
我在学习正则表达式的时候遇到了一个平时都没有注意到的问题,如下:
我想测试多个正则表达式,所以想通过控制台的方式输入正则表达。
public class Main {
public static void main(String args[]){
Scanner in = new Scanner(System.in);
// 正则表达式字符串
// String regex = "^[1-9]\\d*$";
String regex = in.nextLine();
// 输入测试数据
while(true){
String input = in.nextLine();
boolean result = check(regex,input);
System.out.println(result);
}
}
// 检验
public static boolean check(String regex,String input){
boolean result = Pattern.matches(regex, input);
return result;
}
}
我在控制台中输入:
^[1-9]\\d*$
接着输入测试数据:
123
12
1
我发现都只会输出false,而我又在源代码中测试了(也就是不通过控制台的方式输入正则表达)
^[1-9]\\d*$,发现以上的数据均能检验出true
2.问题的引出
- 为什么同样的正则表达式却会有不一样的结果?
- 造成结果不一样的原因是什么?
- 控制台的输入和编写的源码中有何不同?
3.原因的发现
后来我反复多次观察,发现:从源码中编写的 \\d,有效;而在控制台中读取的 \\d,却如同没有作用;
为什么?
答案是在源码中一些特殊的字符需要经过转义处理,而在控制台中就不需要经过转义处理就能存储该字符。
String s1 = "\\n";
System.out.println(s1); // 输出 /n
String s2 = in.nextLine(); // 控制台中输入: /n
System.out.println(s2); // 输出 /n
我们都知道元字符,指本身作为一个字符(字符串)外,还有其它含义。比如: \d,它不仅仅是一个字符串\d,它还是代表着一个数字
我们在java中书写正则表达式时,这里说的书写有两个方面,一是在源代码中书写,二是在控制台中书写
在源代码中,带 \ 的元字符如 \d 要书写为 \\d ,而在控制台中,\d 就不需要书写成 \\d 了
这是因为java的规则,在源码中,\是有特殊含义的,它和其它的一些字母组成转仪字符,如: \b \t \n \r \f \" \’ \*
因为java的规定,所以在源码中不允许单独出现’\',它是要配合一些特定的字符出现,不然就会报错。如果我们在源码中书写正则表达式“-?\d*”,就会因为无法识别\d而报错。因为java认为这是一个转义字符,但是又找不到对应的转义字符匹配。因此 \d 就要写为 \\d,\\ 会通过转义变为为字符 \,d就是d,最终 \\d 就是\d
那为什么在控制台中就不用书写成 \\d 呢?
我认为,在控制台中,我们通过一些输入函数来输入字符,这时的字符就仅仅只是字符了,我们也可以理解为最终存储的字符串,那么这样的话也就不会有源代码码中的先识别是否是转仪字符了,而是直接将字符(如\d)存入
总而言之:在源码中因为要识别是否是转仪字符所以要将 \d书写成\d才能存入,
控制台中直接书写成\d就可以存入.