java 中的 tab 字符转义问题
(2015-10-07 13:26:51)
标签:
365it |
分类: Java |
今天有新同学在写 MR 的过程中,遇到一个问题:
在 hdfs 上有一份 log,里面的内容以 "\t" 字符串(
测试1\t测试2\t测试3\t测试4该同学的 MR 代码大致如下:
System.out.println(line.split("\\t").length)结果全是 1,意味着文本没有按预定模式分割成功。
后来该同学又直接复制文件内容与代码在 eclipse 中测试:
public class Test { public static void main(String[] args) { String line = "测试1\t测试2\t测试3\t测试4"; String[] lineArr = line.split("\\t"); System.out.println(lineArr.length + "\tArr[0]: " + lineArr[0]); } }发现 eclipse 中测试是“没问题”的,然后该同学就猜测 hadoop 环境有问题或者做了二次处理。
其实在之前这篇
现在我们还原下现场,测试尽量详细点:
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class Test { public static void main(String[] args) throws IOException { FileReader reader = new FileReader("C:\\Users\\june\\Desktop\\a.txt"); BufferedReader br = new BufferedReader(reader); String fileLine = null; while ((fileLine = br.readLine()) != null) { String[] lineArr = fileLine.split("\\t"); System.out.println("从文件读,行内容:" + fileLine); System.out.println("Arr.length: " + lineArr.length + "\tArr[0]: " + lineArr[0]); } br.close(); reader.close(); System.out.println("------------------"); String line = "测试1\t测试2\t测试3\t测试4"; String[] lineArr = line.split("\\t"); System.out.println("从字符串读,行内容:" + line); System.out.println("Arr.length: " + lineArr.length + "\tArr[0]: " + lineArr[0]); } }结果:
从文件读,行内容:测试1\t测试2\t测试3\t测试4 Arr.length: 1 Arr[0]: 测试1\t测试2\t测试3\t测试4 ------------------ 从字符串读,行内容:测试1 测试2 测试3 测试4 Arr.length: 4 Arr[0]: 测试1可以看到如果我们直接给字符串赋值,如果带上 \t 的话,是会被转义的,不是字面意义上的 "\t",如果需要字面上的 \t 怎么办呢?
String line = "测试1\\t测试2\\t测试3\\t测试4"; String[] lineArr = line.split("\\\\t"); System.out.println("从字符串读,行内容:" + line); System.out.println("Arr.length: " + lineArr.length + "\tArr[0]: " + lineArr[0]); 结果: 从字符串读,行内容:测试1\t测试2\t测试3\t测试4 Arr.length: 4 Arr[0]: 测试1这里又有同学会问:为什么要 4 个 \\\\ 代表字面意义的 \t 呢?不是两个 \\ 就行了吗?
嗯,还是看代码:
String a1 = "[\t]"; String a2 = "[\\t]"; String a3 = "[\\\t]"; String a4 = "[\\\\t]"; String a5 = "[\\\\\t]"; String a6 = "[\\\\\\t]"; System.out.println(a1); System.out.println(a2); System.out.println(a3); System.out.println(a4); System.out.println(a5); System.out.println(a6); 结果: [ ] [\t] [\ ] [\\t] [\\ ] [\\\t]在 java 解析的时候只有 \t 和 \\t
这个和 shell/awk/python 类似:
june@Win7 192.168.1.100 ~ > echo "测试1\t测试2\t测试3\t测试4"|awk -F'\t' '{print NF"\t"$1}' 1 测试1\t测试2\t测试3\t测试4 june@Win7 192.168.1.100 ~ > echo "测试1\t测试2\t测试3\t测试4"|awk -F'\\t' '{print NF"\t"$1}' 1 测试1\t测试2\t测试3\t测试4 june@Win7 192.168.1.100 ~ > echo "测试1\t测试2\t测试3\t测试4"|awk -F'\\\\t' '{print NF"\t"$1}' 4 测试1 june@Win7 192.168.1.100 ~ >关于字符串的转义与解析,java 算是简单的了,shell 下的水才深,经常让初学者找不着北。例如下面这个结果将会是什么?又如何获取想要的结果呢?
echo "测试1\t测试2\t测试3\t测试4"|awk -F"\\\\t" '{print NF"\t"$1}'