字符串split操作到底有多少坑

微信公众号

微信公众号
长字符串切分,取其中元素封装或者将封装信息组合成长字符串都是常规操作,但是这种长字符串往往是不可控的,如一个长字符串就是由一个元素组成,或者存在空字符串的元素,看似这并没有什么问题,但是使用不同工具类的split方法进行切分结果是完全不同的。不知道你是否遇到这样的坑,下面一起来看看。

String类自带的split方法

直接使用String本身自带的split方法,看对不同字符串的切分结果。

  • 没有分隔符的字符串

    //str = "1"
    public static void split2(String str) {
      String[] splits = str.split(",");
      for (String split : splits) {
          System.out.println("->" + split);
      }
      System.out.println("数组长度:" + splits.length);
    }

    切分后结果是单个元素["1"],数组长度是1。

  • 有分隔符,分隔符切分后没有空字符串出现

    //str = "1,2"
    //代码同上……

    切分后结果是["1","2"],数组长度是2。(假设分隔符是n个,分割后的元素个数是n+1个)

  • 有分隔符,分隔符切分后有空字符串出现

    //str = "1,,2"
    //代码同上……

    切分后结果是["1","","2"],数组长度是3。(假设分隔符是n个,分割后的元素个数是n+1个)

最终总结不管分隔符有多少个,最终切分的结果都是n+1个元素。也是正常业务逻辑所需要的。但是这里有一个问题,如果传入的字符串是null的时候会报NullPointException异常,需要另外加一层非空判断。

commons提供的StringUtils工具类

具体全限定类名是org.apache.commons.lang3.StringUtils,这个可以说是最常用一个字符串的工具类。如判断非null、非空字符串或者非空格,用isNotBlank方法,使用集合元素组装字符串,用join方法等等。现在来看一下split方法在不同的情况下是如何实现。

  • 没有分隔符的字符串

    //str = "1"
    public static void split1(String str) {
      String[] splits = org.apache.commons.lang3.StringUtils.split(str, ",");
      for (String split : splits) {
          System.out.println("->" + split);
      }
      System.out.println("数组长度:" + splits.length);
    }

    切分后的结果是单个元素["1"],数组长度为1。

  • 有分隔符,分隔符切分后没有空字符串出现

    //str = "1,2"
    //代码同上……

    切分后的结果是两个元素["1","2"],数组长度为2。

  • 有分隔符,分隔符切分后有空字符串出现

    //str = "1,,2"
    //代码同上……

    切分后的结果和上一种情况结果是一样的,也是两个元素["1","2"],数组长度为2。

从这里就可以看的出来问题的所在,当出现空字符串的时候,会自动将空字符串丢弃,只保留非空字符串。但是这里还是需要注意的是如果是空格,也会形成一个元素。比如现在str输入的是"1, ,2",两个分隔符间有一个空格,此时就会切分成三个元素。

Spring下util包提供的StringUtils工具类

全限定类名org.springframework.util.StringUtils,这个StringUtils也经常被用到,因为在输入StringUtils的时候,IDEA自动提示,往往它就是在第一位。那它和上面两种在split方法上有什么不同呢?

  • 没有分隔符的字符串

    //str = "1"
    public static void split3(String str) {
      String[] splits = org.springframework.util.StringUtils.split(str, ",");
      for (String split : splits) {
          System.out.println("->" + split);
      }
      System.out.println("数组长度:" + splits.length);
    }

    这个时候对不起,会报NullPointerException异常,也就是这个split方法必须要有分隔符的存在。

  • 有分隔符,分隔符切分后没有空字符串出现

    //str = "1,2"
    //代码同上……

    切分后的结果是两个元素["1","2"],数组长度为2。

  • 有分隔符,分隔符切分后有空字符串出现

    //str = "1,,2"
    //代码同上……

    切分后的结果是两个元素["1",",2"],数组长度为2。看到这里可能你会认为我这个数组格式写错了,但是实际上第二个元素的确是这样的,确定无疑。

这个split方法还是很坑的,它会从字符串中找分隔符是否存在,如果不存在直接报错,如果存在,不管有多少个分隔符,都是以第一个分隔符做切分,最终形成两个元素。

总结

三个split方法三种不同的切分逻辑,到底在什么时候用那种方式切分就很讲究了,因为在开发过程中因为这个切分出过很多莫名其妙的BUG。我就遇到过两次。

  • 第一次是使用的org.apache.commons.lang3.StringUtils来切分字符串,字符串内有空字符串存在,导致切割后的元素个数和实际个数不同,准确的来说少了元素,结果代码中在向另一个字符串占位符中填充数据的时候,总是出现错位的现象。(如本来应该放在占位符3位置上的字符串出现为空字符串,在切分的时候,3位置的元素实际被抛弃,4位置的元素放在了3的位置)
  • 第二次也是使用的org.apache.commons.lang3.StringUtils来切分字符串,测试一直都是很正常,但是测试一段时间后,发现报NullPointException,排查后才发现,引入的StringUtils被其他开发人员换成了org.springframework.util.StringUtils导致的。因为这个字符串可能没有分隔符。
<think>嗯,用户想了解如何去掉字符串中某个字母的方法。看了用户提供的引用资料,涵盖了Java、Python、SQL等多种语言的实现方式。 用户展示的引用内容很全面:引用1和2讲了Java用substring()去除首字母或特定位置字符;引用3展示了C语言用替换函数删除字符;引用4提到Python的trim()和替换方法;引用5则是SQL中处理字符串的示例。这些资料基本覆盖了主流语言的字符删除操作。 用户的需求很明确——不需要理论说明,直接要可用的代码方案。考虑到用户可能面对多种编程场景,应该按语言分类提供解决方案: Java方案的核心思路是用字符串截取(substring)或替换(replace)。比如删除首字母可以直接用str.substring(1),删除任意位置字符则需要配合indexOf定位后拼接前后子串。 Python更简单,直接用replace('a','')就能删除所有'a'字符,或者用切片操作实现位置删除。还能展示列表推导式这种Pythonic写法。 SQL场景比较特殊,引用5用了游标遍历,实际更推荐用REPLACE()函数直接更新字段,比如UPDATE table SET col = REPLACE(col,'a','')。 用户没有指定语言,所以补充通用思路会很有帮助:无论是正则表达式替换,还是转字符数组后过滤重建,都是跨语言通用的底层逻辑。特别提醒用户注意字符串不可变性,避免直接修改原字符串的误区。 最后准备三个实用问题:性能优化适用于大数据量场景,大小写处理是常见点,而删除首尾字符这个高频需求正好能呼应引用1和4的案例。 </think>以下是不同编程语言中**删除字符串中指定字母**的多种方法,按语言分类整理: --- ### **、通用思路** 1. **替换法**:将目标字母替换为空字符串(最常用) 2. **位置截取法**:定位字母位置后拼接剩余部分 3. **遍历过滤法**:遍历字符串并跳过目标字母 --- ### **二、分语言实现** #### **1. Java** ```java // 方法1:替换所有匹配字符 (推荐) String result = str.replace("a", ""); // 删除所有 'a' // 方法2:精准定位删除(删除第个 'a') int index = str.indexOf('a'); if (index != -1) { result = str.substring(0, index) + str.substring(index + 1); } ``` #### **2. Python** ```python # 方法1:replace() 替换 result = s.replace('a', '') # 删除所有 'a' # 方法2:列表推导式 + join() result = ''.join([char for char in s if char != 'a']) # 方法3:正则表达式(复杂场景) import re result = re.sub(r'a', '', s) # 删除所有 'a' ``` #### **3. JavaScript** ```javascript // 方法1:全局替换 let result = str.replace(/a/g, ''); // 删除所有 'a' // 方法2:数组过滤 let result = str.split('').filter(char => char !== 'a').join(''); ``` #### **4. C/C++** ```c #include <stdio.h> #include <string.h> void remove_char(char *str, char c) { int j = 0; for (int i = 0; str[i]; i++) { if (str[i] != c) { str[j++] = str[i]; // 非目标字符前移 } } str[j] = '\0'; // 添结束符 } // 调用示例: char s[] = "banana"; remove_char(s, 'a'); // 输出 "bnn" ``` #### **5. SQL (MySQL示例)** ```sql -- 删除字段中的指定字符 UPDATE table_name SET column_name = REPLACE(column_name, 'a', ''); ``` --- ### **三、关键注意事项** 1. **大小写敏感**:`replace()` 区分大小写(`'A'` ≠ `'a'`) 2. **性能考量**: - 长文本推荐直接替换法(如 `replace()`) - 避免在循环中频繁操作字符串(尤其Java/Python) 3. **扩展场景**: - 删除**首尾**字符:`.trim()`(如引用[4]) - 删除**连续重复**字符:正则表达式 `/(.)\1+/g` --- ### **相关问题** 1. 如何**不区分大小写**地删除字符串中的字母? 2. 删除字符串中的**多个不同字母**有哪些高效方法? 3. 在**超长字符串**中删除字符时如何优化性能? > 参考实现思路源自字符串操作的核心原理:通过**定位**目标字符并重组剩余部分实现删除[^2][^3][^4]。具体语法需根据语言特性调整。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值