Java中使用分隔符分隔标签“\ t”的stringparsing
我正在处理一个制表符分隔的string。 我正在使用split
function来完成这个function,并且在大多数情况下都能正常工作。 问题发生在一个字段丢失,所以而不是在该领域得到空我得到下一个值。 我将分析的值存储在一个string数组中。
String[] columnDetail = new String[11]; columnDetail = column.split("\t");
任何帮助,将不胜感激。 如果可能的话,我想将parsing的string存储到一个string数组中,这样我就可以轻松访问parsing的数据。
String.split使用正则expression式 ,也不需要为你的分割分配一个额外的数组。
拆分方法会给你一个列表。 ,问题是你试图预先定义一个标签有多less次出现,但是你怎么知道呢? 尝试使用扫描仪或StringTokenizer,只是了解如何拆分string的工作。
让我解释一下为什么不行 ,为什么你需要\\\\
好的,所以当你使用Split时,它实际上需要一个正则expression式(正则expression式),而在正则expression式中,你要定义要分割的字符,如果你写了\ t实际上并不意味着\t
和你想要的被\t
分割,对吗? 所以,只要写下你告诉你的正则expression式处理器:“嘿,被逃脱的angular色分割” 不是 “嘿,所有的angular色看起来都像\t
”。 注意区别? 用\意味着逃避某事。 而正则expression式意味着完全不同于你的想法。
所以这就是为什么你需要使用这个解决scheme :
\\t
告诉正则expression式处理器寻找\ t。 好吧,为什么你需要两个? 那么,第一个\逃脱第二个,这意味着它会看起来像这样:\ t当你正在处理文本!
现在让我们说,你正在寻找拆分\
那么你会留下\\但看,这是行不通的! 因为\会试图逃避以前的字符! 这就是为什么你希望输出是\\,因此你需要有\\\\。
我真的希望上面的例子能帮助你理解为什么你的解决scheme不行,如何征服其他的!
现在,我已经给你这个答案 ,也许你现在应该开始看他们。
其他方法
StringTokenizer的
你应该看看StringTokenizer ,这是一个非常方便的工具。
例
StringTokenizer st = new StringTokenizer("this is a test"); while (st.hasMoreTokens()) { System.out.println(st.nextToken()); }
这将输出
this is a test
您使用StringTokenizer的第二个构造函数来设置分隔符:
StringTokenizer(String str, String delim)
扫描器
你也可以使用扫描仪作为评论员之一说这可能看起来有点像这样
例
String input = "1 fish 2 fish red fish blue fish"; Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*"); System.out.println(s.nextInt()); System.out.println(s.nextInt()); System.out.println(s.next()); System.out.println(s.next()); s.close();
输出将是
1 2 red blue
这意味着它将删除“鱼”一词,并用“鱼”作为分隔符给你rest。
从Java API取得的例子
尝试这个:
String[] columnDetail = column.split("\t", -1);
阅读String.split(java.lang.String,int)上的Javadoc ,获取有关split函数limit参数的解释:
split public String[] split(String regex, int limit) Splits this string around matches of the given regular expression. The array returned by this method contains each substring of this string that is terminated by another substring that matches the given expression or is terminated by the end of the string. The substrings in the array are in the order in which they occur in this string. If the expression does not match any part of the input then the resulting array has just one element, namely this string. The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible and the array can have any length. If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing empty strings will be discarded. The string "boo:and:foo", for example, yields the following results with these parameters: Regex Limit Result : 2 { "boo", "and:foo" } : 5 { "boo", "and", "foo" } : -2 { "boo", "and", "foo" } o 5 { "b", "", ":and:f", "", "" } o -2 { "b", "", ":and:f", "", "" } o 0 { "b", "", ":and:f" }
当最后几个字段(我的客人是你的情况)缺失,你会得到这样的列:
field1\tfield2\tfield3\t\t
如果没有限制被设置为split(),则限制为0,这将导致“尾随的空string将被丢弃”。 所以你只能得到3个字段,{“field1”,“field2”,“field3”}。
当limit设置为-1时,一个非正值,尾随空string将不会被丢弃。 所以你可以得到5个字段,最后两个是空string,{“field1”,“field2”,“field3”,“”,“”}。
如果制表符分隔字段本身包含换行符,制表符和可能的“字符,则String.split
实现将受到严重限制。
TAB分隔的格式已经出现在驴的年代,但是格式不是标准化的,而且各不相同。 许多实现不会转义出现在字段中的字符(换行符和制表符)。 相反,他们遵循CSV约定,并在“双引号”中包含任何非平凡的字段。 然后他们逃脱只有双引号。 所以一条“线”可以延伸到多条线上。
我周围的阅读听到“只是重用Apache工具”,这听起来像很好的build议。
最后我个人select了opencsv 。 我发现它是轻量级的,并且由于它提供了用于转义和引用字符的选项,它应该涵盖大多数stream行的逗号和制表符分隔的数据格式。
例:
CSVReader tabFormatReader = new CSVReader(new FileReader("yourfile.tsv"), '\t');
没有人回答 – 这是部分问题的错误:inputstring包含十一个字段(这可以推断),但有多less标签? 最可能正好是 10.然后答案是
String s = "\t2\t\t4\t5\t6\t\t8\t\t10\t"; String[] fields = s.split("\t", -1); // in your case s.split("\t", 11) might also do for (int i = 0; i < fields.length; ++i) { if ("".equals(fields[i])) fields[i] = null; } System.out.println(Arrays.asList(fields)); // [null, 2, null, 4, 5, 6, null, 8, null, 10, null] // with s.split("\t") : [null, 2, null, 4, 5, 6, null, 8, null, 10]
如果字段碰巧包含标签,这当然不会像预期的那样工作。
-1
意味着:根据需要多次应用模式 – 所以尾部字段(第11个)将被保留(如果空string( ""
),如果不存在,需要明确地将其转换为null
)。
另一方面,如果缺less字段没有选项卡 – 所以"5\t6"
是一个有效的inputstring,只包含字段5,6 – 没有办法通过拆分获得fields[]
。
我刚刚有同样的问题,并注意到某种教程的答案。 一般来说,你需要使用split方法的第二种forms,使用
split(regex, limit)
这里是完整的教程http://www.rgagnon.com/javadetails/java-0438.html
如果你为极限参数设置了一些负数,你将会得到数组中缺less实际值的空串。 要使用这个,你的初始string应该有两个分隔符的副本,也就是你应该有缺less值的地方。
希望这可以帮助 :)