String的Split方法的用法与要注意事项
- 转自:http://shukuiyan.iteye.com/blog/1058672
- 之前在http://shukuiyan.iteye.com/blog/507915文中已经叙述过这个问题,但是最近一次笔试中居然有碰到了这个知识点,而且还做错了,囧!学艺不精啊。题目大概是这样的:
- Java代码
- String s2="this is a test";
- String sarray[]=s2.split("/s");
- System.out.println("sarray.length="+sarray.length);
- 这个输出是什么还是编译出错?我想那个split方法中的参数要是"s"的话,输出一定是4了,就是将原来字符串分成了数组{"thi","i","a te","t"},但是原题split方法中的参数要是"/s",那么这个参数到底是嘛意思呢,实验后输出结果居然是1。
- 原因还得深究啊。
- java.lang.string.split,即split 方法,它实现的功能是将一个字符串分割为子字符串,然后将结果作为字符串数组返回。 格式为:
- stringObj.split([separator,[limit]])
- 其中stringObj是必选项,表示要被分解的 String 对象或文字。该对象不会被 split 方法修改。 separator 为可选项,表示字符串或正则表达式对象,它标识了分隔字符串时使用的是一个还是多个字符。如果忽略该选项,返回包含整个字符串的单一元素数组。 limit 为可选项,该值用来限制返回数组中的元素个数。 值得注意的是: split 方法的结果是一个字符串数组,在 stingObj 中每个出现 separator 的位置都要进行分解,separator 不作为任何数组元素的部分返回。
- 一个例子
- Java代码
- String srcstring="this is a about split test";
- String stringarray[]=srcstring.split(" ");
- //// 在每个空格字符处进行分解
- for(String stemp:stringarray){
- System.out.println(stemp);
- }
- String srcstring1=" this is a about split test";//有n个空格的话,分成的数组长度为n+1
- //如果字符串中有多个空格时,则两个空格间认为是没有字符,结果字符串数组中该位置为空。
- String stringarray1[]=srcstring1.split(" ");
- for(String stemp:stringarray1){
- System.out.println(stemp);
- }
- 这样输出结果为
- Java代码
- this
- is
- a
- about
- split
- test
- 另一个:
- this
- is
- a
- about
- split
- test
- 另外一个例子
- Java代码
- String srcstring="this is a about split test";
- String stringarray[]=srcstring.split(" ",);
- //// 在每个空格字符处进行分解
- for(String stemp:stringarray){
- System.out.println(stemp);
- }
- 输出结果为
- this
- is a about split test
- 看看下面这个
- Java代码
- String ipstring="59.64.159.224";
- String iparray[]=ipstring.split(".");
- for(String stemp:iparray){
- System.out.println(stemp);
- }
- 这个输出为空,为什么呢?
- 因为 public string[] split(string regex) 这里的参数的名称是regex ,也就是 regular expression (正则表达式)。这个参数并不是一个简单的分割用的字符,而是一个正则表达式,以下是split 方法的实现代码:
- public string[] split(string regex, int limit) {
- return pattern.compile(regex).split(this, limit);
- }
- split 的实现直接调用的 matcher 类的 split 的方法。我们知道,“ . ”在正则表达式中有特殊的含义,因此我们使用的时候必须进行转义。 只要将
- Java代码
- String iparray[]=ipstring.split(".");
- 改为
- Java代码
- String iparray[]=ipstring.split("\\.");
- 就可以了。
- 那么这里在列上一些转义字符
- \\ 反斜杠
- \t 间隔 ('\u0009')
- \n 换行 ('\u000A')
- \r 回车 ('\u000D')
- \d 数字 等价于 [-]
- \D 非数字 等价于 [^-]
- \s 空白符号 [\t\n\x0B\f\r]
- \S 非空白符号 [^\t\n\x0B\f\r]
- \w 单独字符 [a-zA-Z_0-]
- \W 非单独字符 [^a-zA-Z_0-]
- \f 换页符
- \e Escape
- \b 一个单词的边界
- \B 一个非单词的边界
- \G 前一个匹配的结束
- 注意:public String[] split(String regex,int limit)根据匹配给定的正则表达式来拆分此字符串。
- 此方法返回的数组包含此字符串的每个子字符串,这些子字符串由另一个匹配给定的表达式的子字符串终止或由字符串结束来终止。数组中的子字符串按它们在此字符串中的顺序排列。如果表达式不匹配输入的任何部分,则结果数组只具有一个元素,即此字符串。
- limit 参数控制模式应用的次数,因此影响结果数组的长度。如果该限制 n 大于 ,则模式将被最多应用 n - 次,数组的长度将不会大于 n,而且数组的最后项将包含超出最后匹配的定界符的所有输入。如果 n 为非正,则模式将被应用尽可能多的次数,而且数组可以是任意长度。如果 n 为零,则模式将被应用尽可能多的次数,数组可有任何长度,并且结尾空字符串将被丢弃。
- 回到最初的题目,题目中给出的匹配正则表达式为"/s",表示空白字符,此时给定的字符串中没有匹配的字符,则输出为原字符串,所以输出的字符长度为1.
- 再附上一些关于java中正则表达式的知识吧
- ^ 为限制开头
- ^java 条件限制为以 Java 为开头字符
- $ 为限制结尾
- java$ 条件限制为以 java 为结尾字符
- . 条件限制除 \n 以外任意一个单独字符
- java.. 条件限制为 java 后除换行外任意两个字符
- 加入特定限制条件「 [] 」
- [a-z] 条件限制在小写 a to z 范围中一个字符
- [A-Z] 条件限制在大写 A to Z 范围中一个字符
- [a-zA-Z] 条件限制在小写 a to z 或大写 A to Z 范围中一个字符
- [-] 条件限制在小写 to 范围中一个字符
- [-9a-z] 条件限制在小写 to 或 a to z 范围中一个字符
- [-[a-z]] 条件限制在小写 to 或 a to z 范围中一个字符 ( 交集 )
- [] 中加入 ^ 后加再次限制条件「 [^] 」
- [^a-z] 条件限制在非小写 a to z 范围中一个字符
- [^A-Z] 条件限制在非大写 A to Z 范围中一个字符
- [^a-zA-Z] 条件限制在非小写 a to z 或大写 A to Z 范围中一个字符
- [^-] 条件限制在非小写 to 范围中一个字符
- [^-9a-z] 条件限制在非小写 to 或 a to z 范围中一个字符
- [^-[a-z]] 条件限制在非小写 to 或 a to z 范围中一个字符 ( 交集 )
- 在限制条件为特定字符出现 次以上时,可以使用「 * 」
- J* 个以上 J
- .* 个以上任意字符
- J.*D J 与 D 之间 个以上任意字符
- 在限制条件为特定字符出现 次以上时,可以使用「 + 」
- J+ 个以上 J
- .+ 个以上任意字符
- J.+D J 与 D 之间 个以上任意字符
- 在限制条件为特定字符出现有 或 次以上时,可以使用「 ? 」
- JA? J 或者 JA 出现
- 限制为连续出现指定次数字符「 {a} 」
- J{} JJ
- J{} JJJ
- 文字 a 个以上,并且「 {a,} 」
- J{,} JJJ,JJJJ,JJJJJ,???( 次以上 J 并存 )
- 文字个以上, b 个以下「 {a,b} 」
- J{,} JJJ 或 JJJJ 或 JJJJJ
- 两者取一「 | 」
- J|A J 或 A
- Java|Hello Java 或 Hello
- 「 () 」中规定一个组合类型
- 比如,我查询 <a href=\"index.html\">index</a> 中 <a href></a> 间的数据,可写作 <a.*href=\".*\">(.+?)</a>
- 在使用 Pattern.compile 函数时,可以加入控制正则表达式的匹配行为的参数:
- Pattern Pattern.compile(String regex, int flag)
- flag 的取值范围如下:
- Pattern.CANON_EQ 当且仅当两个字符的 " 正规分解 (canonical decomposition)" 都完全相同的情况下,才认定匹配。比如用了这个标志之后,表达式 "a\u030A" 会匹配 "?" 。默认情况下,不考虑 " 规范相等性 (canonical equivalence)" 。
- Pattern.CASE_INSENSITIVE(?i) 默认情况下,大小写不明感的匹配只适用于 US-ASCII 字符集。这个标志能让表达式忽略大小写进行匹配。要想对 Unicode 字符进行大小不明感的匹配,只要将 UNICODE_CASE 与这个标志合起来就行了。
- Pattern.COMMENTS(?x) 在这种模式下,匹配时会忽略 ( 正则表达式里的 ) 空格字符 ( 译者注:不是指表达式里的 "\\s" ,而是指表达式里的空格, tab ,回车之类 ) 。注释从 # 开始,一直到这行结束。可以通过嵌入式的标志来启用 Unix 行模式。
- Pattern.DOTALL(?s) 在这种模式下,表达式 '.' 可以匹配任意字符,包括表示一行的结束符。默认情况下,表达式 '.' 不匹配行的结束符。
- Pattern.MULTILINE
- (?m) 在这种模式下, '^' 和 '$' 分别匹配一行的开始和结束。此外, '^' 仍然匹配字符串的开始, '$' 也匹配字符串的结束。默认情况下,这两个表达式仅仅匹配字符串的开始和结束。
- Pattern.UNICODE_CASE
- (?u) 在这个模式下,如果你还启用了 CASE_INSENSITIVE 标志,那么它会对 Unicode 字符进行大小写不明感的匹配。默认情况下,大小写不敏感的匹配只适用于 US-ASCII 字符集。
- Pattern.UNIX_LINES(?d) 在这个模式下,只有 '\n' 才被认作一行的中止,并且与 '.' , '^' ,以及 '$' 进行匹配。
- 抛开空泛的概念,下面写出几个简单的 Java 正则用例:
- ◆ 比如,在字符串包含验证时
- // 查找以 Java 开头 , 任意结尾的字符串
- Pattern pattern = Pattern.compile("^Java.*");
- Matcher matcher = pattern.matcher("Java 不是人 ");
- boolean b= matcher.matches();
- // 当条件满足时,将返回 true ,否则返回 false
- System.out.println(b);
- ◆ 以多条件分割字符串时
- Pattern pattern = Pattern.compile("[, |]+");
- String[] strs = pattern.split("Java Hello World Java,Hello,,World|Sun");
- for (int i=;i<strs.length;i++) {
- System.out.println(strs[i]);
- }
- ◆ 文字替换(首次出现字符)
- Pattern pattern = Pattern.compile(" 正则表达式 ");
- Matcher matcher = pattern.matcher(" 正则表达式 Hello World, 正则表达式 Hello World");
- // 替换第一个符合正则的数据
- System.out.println(matcher.replaceFirst("Java"));
- ◆ 文字替换(全部)
- Pattern pattern = Pattern.compile(" 正则表达式 ");
- Matcher matcher = pattern.matcher(" 正则表达式 Hello World, 正则表达式 Hello World");
- // 替换第一个符合正则的数据
- System.out.println(matcher.replaceAll("Java"));
- ◆ 文字替换(置换字符)
- Pattern pattern = Pattern.compile(" 正则表达式 ");
- Matcher matcher = pattern.matcher(" 正则表达式 Hello World, 正则表达式 Hello World ");
- StringBuffer sbr = new StringBuffer();
- while (matcher.find()) {
- matcher.appendReplacement(sbr, "Java");
- }
- matcher.appendTail(sbr);
- System.out.println(sbr.toString());
- ◆ 验证是否为邮箱地址
- String str="ceponline@yahoo.com.cn";
- Pattern pattern = Pattern.compile("[\\w\\.\\-]+@([\\w\\-]+\\.)+[\\w\\-]+",Pattern.CASE_INSENSITIVE);
- Matcher matcher = pattern.matcher(str);
- System.out.println(matcher.matches());
- ◆ 去除 html 标记
- Pattern pattern = Pattern.compile("<.+?>", Pattern.DOTALL);
- Matcher matcher = pattern.matcher("<a href=\"index.html\"> 主页 </a>");
- String string = matcher.replaceAll("");
- System.out.println(string);
- ◆ 查找 html 中对应条件字符串
- Pattern pattern = Pattern.compile("href=\"(.+?)\"");
- Matcher matcher = pattern.matcher("<a href=\"index.html\"> 主页 </a>");
- if(matcher.find())
- System.out.println(matcher.group());
- }
- ◆ 截取 http:// 地址
- // 截取 url
- Pattern pattern = Pattern.compile("(http://|https://){1}[\\w\\.\\-/:]+");
- Matcher matcher = pattern.matcher("dsdsds<http://dsds//gfgffdfd>fdf");
- StringBuffer buffer = new StringBuffer();
- while(matcher.find()){
- buffer.append(matcher.group());
- buffer.append("\r\n");
- System.out.println(buffer.toString());
- }
- ◆ 替换指定 {} 中文字
- String str = "Java 目前的发展史是由 {0} 年 -{1} 年 ";
- String[][] object={new String[]{"\\{0\\}",""},new String[]{"\\{1\\}",""}};
- System.out.println(replace(str,object));
- public static String replace(final String sourceString,Object[] object) {
- String temp=sourceString;
- for(int i=;i<object.length;i++){
- String[] result=(String[])object[i];
- Pattern pattern = Pattern.compile(result[]);
- Matcher matcher = pattern.matcher(temp);
- temp=matcher.replaceAll(result[]);
- }
- return temp;
- }
- ◆ 以正则条件查询指定目录下文件
- // 用于缓存文件列表
- private ArrayList files = new ArrayList();
- // 用于承载文件路径
- private String _path;
- // 用于承载未合并的正则公式
- private String _regexp;
- class MyFileFilter implements FileFilter {
- /**
- * 匹配文件名称
- */
- public boolean accept(File file) {
- try {
- Pattern pattern = Pattern.compile(_regexp);
- Matcher match = pattern.matcher(file.getName());
- return match.matches();
- } catch (Exception e) {
- return true;
- }
- }
- }
但是我在将字符串“E:\svntest\mm\impProject\cisco_config.txt”用“\”分割的时候出现了问题。我是这样写的:
- String[] files=filePath.split("\\"); //其中filePath="E:\svntest\mm\impProject\cisco_config.txt";
- 但是我按照上面这种写法竟然错了!!!
最后看了一篇博客:
- 我们都知道 String s="ad,dfjdlfs,df,s,dfl";
- 执行 String re[]=s.split(",");
- 则re的数组将是re[]="ad" re[]="dfjdlfs" re[]="df" re[]="s" re[]="dfl"
- 同理 String s="an|ddd|aed"
- 执行 String re[]=s.split("|");
- 结果中却 re[]="" re[]="a" re[]="n" re[]="|" re[]="d" ........
- 刚开始不知道怎么回事?
- 后来查了java的转义字符
- .八进制转义序列:\ + 1到3位5数字;范围'\000'~'\377' \:空字符
- .Unicode转义字符:\u + 四个十六进制数字;~ \u0000:空字符
- .特殊字符:就3个
- \":双引号
- \':单引号
- \\:反斜线
- .控制字符:5个
- \' 单引号字符
- \\ 反斜杠字符
- \r 回车
- \n 换行
- \f 走纸换页
- \t 横向跳格
- \b 退格
- 点的转义:. ==> u002E
- 美元符号的转义:$ ==> u0024
- 乘方符号的转义:^ ==> u005E
- 左大括号的转义:{ ==> u007B
- 左方括号的转义:[ ==> u005B
- 左圆括号的转义:( ==> u0028
- 竖线的转义:| ==> u007C
- 右圆括号的转义:) ==> u0029
- 星号的转义:* ==> u002A
- 加号的转义:+ ==> u002B
- 问号的转义:? ==> u003F
- 反斜杠的转义: ==> u005C
- 后来改成:
- String s="an|ddd|aed" 执行 String re[]=s.split(\\u007C);
- 结果就是我想要的了 re[]="an" re[]="ddd" re[]="aed"
才恍然大悟:
将代码改成这样就对了:
- String[] files=filePath.split("\\u005C");
String的Split方法的用法与要注意事项的更多相关文章
- String的split方法,你真的懂吗
String的split方法相信大家都不陌生,或多或少都用过它将字符串转成一个数组,但是就是这样一个简单的方法,里面也有一个不得不注意.不深不浅的小坑. 本地测试代码如下图所示: 图1 大家会发现sp ...
- String的split方法支持正则表达式
String的split方法支持正则表达式: 1. 正则表达式\s表示匹配任何空白字符 2. +表示匹配一次或多次
- String 对象-->split() 方法
1.定义和用法 split() 方法用于把一个字符串分割成字符串数组. 语法: string.split(separator,limit) 参数: separator:可选.字符串或正则表达式,从该参 ...
- String的split()方法探索和大揭秘
事实上没打算写这么一篇博文的,可是昨天在逛论坛的时候,发现一帖子,然后我又把帖子的内容在群里发了一通,结果出现了让人吃惊的结果,所以这里简单的给大家分享一下split()方法,免得大伙儿以后还会出现这 ...
- 关于String的split方法
在做剑指offer的时候,有一道替换空格的题,立刻就想到用这个split方法来做,但发现,这个方法会丢掉字符串最后的空格??? 百度后,知道原因,这里直接复制粘贴了: 在使用java中的split按照 ...
- Java中String的split()方法的一些需要注意的地方
public String[] split(String regex, int limit) split函数是用于使用特定的切割符(regex)来分隔字符串成一个字符串数组,这里我就不讨论第二个参数( ...
- Java中String的split()方法的一些疑问和试验
http://tjuking.iteye.com/blog/1507855 和我想的还是不大一样,因为不知道源码也不知道具体是怎么实现的,我的理解如下: 当字符串只包含分隔符时,返回数组没有元素:当字 ...
- 【blog】批量删除时,guava Splitter与Java String的split 方法有什么区别
参考链接 http://www.cnblogs.com/hxfirefox/p/4832913.html
- String 基本使用方法, 以及要注意的事项
package chengbaoDemo; public class Test01 { public static void main(String[] args) { //字符串的两种创建形式 St ...
随机推荐
- C# MVC 自学笔记—2 MVC Movie简介
MVC Movie是微软官方的一个MVC入门项目,我们可以跟着这个项目来实践入门 这是官方地址 http://www.asp.net/mvc/tutorials/mvc-4/getting-start ...
- 记一个手游app数据文件的破解
出于一些非常猥琐的须要,同一时候自己也想做一些新奇的尝试,周末用了大半天时间破解了某款手游的数据文件. 过程比我预想的要顺利,主要原因还是我们开发者的懈怠.咳咳. 步骤例如以下: 下载安装包,解压,发 ...
- Linux红黑树(二)——访问节点
核心对红黑树使用两点说明 1.头文件 <Documentation/rbtree.txt> Linux's rbtree implementation lives in the file ...
- C++编程规范之11:隐藏信息
摘要: 不要泄密,不要公开提供抽象的实体的内部信息. 为了尽量减少操作抽象的调用代码和抽象的实现之间的依赖性,必须隐藏实现内部的数据.否则,调用代码就能够访问该信息,或者更糟,操作该信息,而原来应属于 ...
- TMsgThread, TCommThread -- 在delphi线程中实现消息循环(105篇博客,好多研究消息的文章)
在delphi线程中实现消息循环 在delphi线程中实现消息循环 Delphi的TThread类使用很方便,但是有时候我们需要在线程类中使用消息循环,delphi没有提供. 花了两天的事件研究了 ...
- POJ 2632 Crashing Robots(较为繁琐的模拟)
题目链接:http://poj.org/problem?id=2632 题目大意:题意简单,N个机器人在一个A*B的网格上运动,告诉你机器人的起始位置和对它的具体操作,输出结果: 1.Robot i ...
- Linux Shell 之 Shell中的函数调用
说起函数调用,相信大家也不会陌生,然而对于初学Shell的我来说,Shell中函数调用方式却有点让我不太习惯,自己也走了不少的弯路,因为传递参数时出了一个很“自然”的错误,也让我吃了不少的苦头,所以总 ...
- hadoop namanodejava
最近突然想看下hadoop源码,有利于处理一些突发问题.先从name启动开始, NameNode.java public static void main(String argv[]) throws ...
- spring开发基础
Spring是一个开源框架,它由Rod Johnson创建.它是为了解决企业应用开发的复杂性而创建的.Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情.然而,Spring的用途 ...
- 使用AjaxFileUpload.js实现文件异步上�
ajax是无法提交文件的,所以在上传图片并预览的时候,我们常常使用Ifame的方法实现看似异步的效果.可是这样总不是非常方便的,AjaxFilleUpload.js对上面的方法进行了一个包装,使得我们 ...