为什么 trim 函数无法正常工作?

20

我想从字符串中去除前导空格,但是我不知道我的方法有什么问题,欢迎提出任何建议。

代码:

this.poNumber = poNumber.equals("") ? poNumber : poNumber.trim();

我从csv文件中读取了poNumber,其值为 "     IG078565 and IG083060 ",并且输出的结果也是相同的带有相同的空格,不确定原因是什么?

更新

为了更好的上下文,添加完整的方法:

public BillingDTO(String currency, String migrationId, String chargeId, String priceId, String poNumber, String otc,
            String billingClassId, String laborOnly) {
        super();
        this.currency = currency.equals("") ? currency : currency.trim();
        this.migrationId = migrationId.equals("") ? migrationId : migrationId.trim();
        this.chargeId = chargeId.equals("") ? chargeId : chargeId.trim();
        this.priceId = priceId.equals("") ? priceId : priceId.trim();
        this.poNumber = poNumber.equals("") ? poNumber : poNumber.trim();
            //poNumber.trim();
        //System.out.println("poNumber:"+this.poNumber.trim());
        //this.poNumber = poNumber.equals("") ? poNumber : poNumber.trim();
        this.otc = otc.equals("") ? otc : otc.trim();
        this.billingClassId = billingClassId.equals("") ? billingClassId : billingClassId.trim();
        this.laborOnly = laborOnly.equals("") ? "N" : laborOnly;
    }

谢谢。


1
你期望这段代码做什么,它实际上做了什么? - Michael Borgwardt
@Michael:代码应该检查值是否为 NULL,如果是,则按原样插入数据库;如果不是 NULL,则应删除前导和尾随空格,然后再插入。 - Rachel
1
我注意到你在赋值语句的左边使用了 this.poNumber,而在右边只使用了 poNumber。这是因为既有实例变量又有局部变量都叫做 poNumber吗? - mikej
1
@Rachel:你不能期待poNumber在后面被修剪,只有 this.poNumber可以。你是遇到哪个错误了? - Mark Peters
可能是如何在Java中正确地修剪字符串中的空格?的重复问题。 - Matt Ball
显示剩余2条评论
4个回答

48

更新:看起来你的空白字符不是普通的空格(ASCII码为32),而是使用了代码160的不间断空格。 trim() 方法无法处理它。因此,你需要像这样进行处理:

this.poNumber = poNumber.replace(String.valueOf((char) 160), " ").trim();

最好创建一个实用程序-YourStringUtils.trim(string),并在那里执行这两个操作-.trim()replace(..)


翻译后的答案:

只需使用 this.poNumber = poNumber.trim();

如果有可能出现 poNumbernull 的情况,则可以使用来自commons-lang的 null-safe this.poNumber = StringUtils.trim(poNumber);

您还可以使用该类中的 trimToEmpty(..),如果希望将 null 转换为空字符串。

如果您不想依赖于commons-lang,那么只需添加 if 语句:

if (poNumber != null) {
    this.poNumber = poNumber.trim();
}

如问题下方的评论所述,请确保在修剪后检查正确的变量。您应该检查实例变量。由于字符串是不可变的,因此参数(或局部变量,我无法确定)不会更改。


1
@Rachel - 我添加了关于 null 的更新。你的代码也会返回 null。 - Bozho
@Rachel,请看我的最后一段。 - Bozho
@Bozho:我不确定如何找到一个字符的ASCII码? - Rachel
2
太棒了,Bozho的回答救了我的一命!只是作为一个小调整,我建议使用replace(String.valueOf((char) 160), " ");而不是replace(String.valueOf((char) 160), "");(即用真正的空格替换非断行空格,然后再由trim()删除)。这样,如果您要修剪的字符串中有其他非断行空格,则它们将被替换为普通空格而不是空白。 - Andy
3
可以使用replace((char) 160, ' ')替代。 - marwinXXII
显示剩余11条评论

3

您确定读取的是正确的变量用于输出吗?您有'poNumber',它是原始未修剪的字符串,以及'this.poNumber',它将获得修剪后的字符串。


1

您的文件可能包含未被修剪的非ASCII空格。例如,有一个Unicode字符不间断空格(U+00A0),它显示为空格但不被trim函数考虑(这是您在WordPad或其他编辑器中编辑文档时可能会遇到的情况)。如果您查看String.trim()的定义,它会删除小于或等于20的字符(即值小于或等于20)。

因此,请打印字符串的字节值(或在十六进制编辑器中查看),确保您的空格实际上是空格(即十进制值为20)。如果您需要其他行为,则可能需要编写自己的trim实用程序函数,该函数使用适当的Unicode Character.isWhiteSpace(char)检查。


如何做到这一点,我不确定我们如何打印字节码值。 - Rachel
小提示 - “十进制值20”可能应该改为“十六进制值20”或“十进制值32”... - weiresr

1

您可以使用这个函数,我对Java的trim()方法进行了一些操作,这比一些replace()方法更好、更快、更有效。

public static String trimAdvanced(String value) {

        Objects.requireNonNull(value);

        int strLength = value.length();
        int len = value.length();
        int st = 0;
        char[] val = value.toCharArray();

        if (strLength == 0) {
            return "";
        }

        while ((st < len) && (val[st] <= ' ') || (val[st] == '\u00A0')) {
            st++;
            if (st == strLength) {
                break;
            }
        }
        while ((st < len) && (val[len - 1] <= ' ') || (val[len - 1] == '\u00A0')) {
            len--;
            if (len == 0) {
                break;
            }
        }


        return (st > len) ? "" : ((st > 0) || (len < strLength)) ? value.substring(st, len) : value;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接