【问题标题】:Don't trim tab(\t) from start/end of a String in JAVA不要在 JAVA 中从字符串的开头/结尾修剪制表符(\t)
【发布时间】:2019-08-30 10:19:15
【问题描述】:

我有一个输入流,它的字段由 tab(\t) 分隔 看起来像这样

String str = "  acc123\tdpId123\t2011-01-01\t2022-01-01\thello@xyz.com\tIN\t1233\tSOMETHING      ";

当我使用str = str.trim();

时效果很好
strArray = str.split("\t", -1); 
strArray=["acc123","dpId123","2011-01-01","2022-01-01","hello@xyz.com","IN","1233","SOMETHING"] will give size as 8 

但输入记录的最后一个字段不是必须的,可以跳过。

所以输入也可以是这样的。

 String str1 = "acc123\tdpId123\t2011-01-01\t2022-01-01\thello@xyz.com\tIN\t1233\t";

但在这种情况下,最后一个字段应该为空,但是当我在修剪和拆分后使用此字符串时,我的大小为 7

str1 = str1.trim();      
strArray = str1.split("\t", -1); 
      strArray=["acc123","dpId123","2011-01-01","2022-01-01","hello@xyz.com","IN","1233"]will give size as 7

但我想要

strArray=["acc123","dpId123","2011-01-01","2022-01-01","hello@xyz.com","IN","1233",""]

我怎样才能避免这种情况?

【问题讨论】:

  • 对于您提供给我们的两个示例字符串,您希望看到的实际输出是什么,以及决定您希望看到什么的规则是什么?
  • 为什么要修剪没有前导或尾随空格的字符串?只是不要修剪它!
  • 更新描述
  • @AjahnCharles 我可能会在字符串的开头和结尾出现空格,这是意料之中的。我也改变了第一个例子。
  • 可以先分割再修剪吗?

标签: java string trim


【解决方案1】:

你去吧:

String str1 = "   acc123\tdpId 123\t201 1-01-01\t2022-01-01\thello@xyz.com\tIN\t1233\t";
str1 = str1.replaceAll("^[ ]+", ""); // removing leading spaces
str1 = str1.replaceAll("[ ]+$", ""); // removing trailing spaces
String[] split = str1.split("\t", -1);

System.out.println(Arrays.toString(split));
System.out.println(split.length);

String#trim 方法也会删除\t。为了解决这个问题,我使用正则表达式仅删除了前导和尾随空格。

输出:

[acc123, dpId 123, 201 1-01-01, 2022-01-01, hello@xyz.com, IN, 1233, ]
8

【讨论】:

  • 它也会替换我字段中的所有空格。
  • @Bhavesh 检查输出。它没有替换字段内的空格。
  • 是的。此正则表达式仅匹配前导和尾随空格(没有其他空格)。
  • @Bhavesh 如果它解决了您的问题,请考虑接受此答案。
【解决方案2】:

你可以像这样使用拆分:

String[] split = str.split("\t", -1); // note the -1

为了避免空格,你可以使用

 Arrays.stream(split).map(String::trim).toArray(String[]:new);

【讨论】:

  • 你能解释一下 -1 的作用吗?
  • @AjahnCharles “limit 参数控制应用模式的次数,因此会影响结果数组的长度” - 来自 java 文档
  • @Bhavesh 抱歉,我正在使用电话接听,但 Faris 是正确的,使用此解决方案您应该看到 \t 将转换为空,您将进入 str1 8 元素分割结果
  • @YCF_L 这看起来像拆分然后修剪所有字段。如果我错了,请纠正我
  • @Mushif Ali Nawaz 这是正确的问题缺少某些情况,这使得很难猜测 OP 到底想要什么
【解决方案3】:

你可以使用limit参数来解决这个str.split("\t",-1)

limit 参数控制模式应用的次数,因此会影响结果数组的长度。

docs 中阅读有关拆分限制的更多信息。

示例:

public class GFG { 
    public static void main(String args[]) 
    { 
        String str = "a\tb\tc\t"; 
        String[] arrOfStr = str.split("\t",-1); 

        for (String a : arrOfStr) 
            System.out.println(a);
        System.out.println(arrOfStr.length);
    } 

} 

【讨论】:

    【解决方案4】:

    在您的情况下,概念上正确的方法是先拆分,然后再修剪第一个和最后一个元素:

    String[] array = str.split("\t");
    array[0] = array[0].trim();
    int last = array.length -1;
    if (last > 0) {
        array[last] = array[last].trim();
    }
    

    另外,如果您预先知道应该有多少字段,那么您也应该使用该知识,否则您仍然可以获得无效数量的字段:

    int fieldsCount = getExpectedFieldsCount();
    String[] array = str.split("\t", fieldsCount);
    

    最后,我建议您不要使用空格作为数据分隔符。用别的东西。比如看CSV格式,这些东西就好多了。

    【讨论】:

    • 您使用 CSV 格式是对的。但是对于我的库代码,我也确实想支持 tab \t 。用例可以是如果输入字段包含用户的地址。并且地址字段可以有逗号。
    • @Bhavesh,它已经以格式处理。如果字段数据包含分隔符,则该单元格的数据用双引号括起来。在您的情况下,任何和所有字段也可以包含一个选项卡,因此您遇到了同样的问题,只是(可能)不那么明显。
    【解决方案5】:

    试试这个(结果数组在变量resultArray中):

        String str1 = "acc123\tdpId123\t2011-01-01\t2022-01-01\thello@xyz.com\tIN\t1233\t";
        String[] strArray = str1.split("\t");
        String regex = ".*\\t$";
        String[] resultArray;
        if (str1.matches(regex)) {
            resultArray = new String[strArray.length + 1];
            resultArray[strArray.length] = "";
        } else {
            resultArray = new String[strArray.length];
        }
        for (int i= 0; i < strArray.length; i++) {
            resultArray[i] = strArray[i];
        }
    
        System.out.println(resultArray.length);
        System.out.println(Arrays.toString(resultArray));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-01
      • 2021-05-12
      • 1970-01-01
      • 1970-01-01
      • 2013-08-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      相关资源
      最近更新 更多