前面介绍了处理字符串的经常使用方法,还有一种分割字符串的场景也很常见,也就是按照某个规则将字符串切割为若干子串。分割规则一般是指定某个分隔符,根据字符串内部的分隔符将字符串进行分割,例如逗号、空格等等均可以做为字符串的分隔符。正好String类型提供了split方法用于切割字符串,只要字符串变量调用split方法,并把分隔符做为输入参数,该方法便可返回分割好的字符串数组。
下面的split调用代码例子演示了如何按照逗号和空格切割字符串:html
// 经过逗号分割字符串 private static void splitByComma() { String commaStr = "123,456,789"; // 利用split方法指定按照逗号切割字符串 String[] commaArray = commaStr.split(","); for (String item : commaArray) { System.out.println("comma item = "+item); } } // 经过空格分割字符串 private static void splitBySpace() { String spaceStr = "123 456 789"; // 利用split方法指定按照空格切割字符串 String[] spaceArray = spaceStr.split(" "); for (String item : spaceArray) { System.out.println("space item = "+item); } }
除了逗号和空格之外,点号和竖线也经常用来分隔字符串,可是对于点号和竖线,split方法的调用代码不会获得预期的结果。相反,split(".")没法获得分割后的字符串数组,也就是说结果的字符串数组为空;而split("|")分割获得的字符串数组,每一个数组元素只有一个字符,其结果相似于toCharArray。究其缘由,缘于split方法的输入参数理应是个正则串,并不是普通的分隔字符。因为点号和竖线都是正则串的保留字符,所以没法直接在正则串中填写,必须进行转义处理方可。如同回车符和换行符在普通字符串中经过前缀的反斜杆转义那样(回车符对应\r,换行符对应\n),正则字符串经过在原字符前面添加两个反斜杆来转义,像点号字符在正则串中对应的转义符为“\\.”,而竖线在正则串中对应的转义符为“\\|”。通过转移处理以后,经过点号和竖线切割字符串的正确代码写法以下所示:java
// 经过点号分割字符串 private static void splitByDot() { String dotStr = "123.456.789"; // split(".")没法获得分割后的字符串数组 //String[] dotArray = dotStr.split("."); // 点号是正则串的保留字符,须要进行转义(在点号前面加两个反斜杆) String[] dotArray = dotStr.split("\\."); for (String item : dotArray) { System.out.println("dot item = "+item); } } // 经过竖线分割字符串 private static void splitByLine() { String lineStr = "123|456|789"; // split("|")分割获得的字符串数组,每一个数组元素只有一个字符,相似于toCharArray的结果 //String[] lineArray = lineStr.split("|"); // 竖线是正则串的保留字符,须要进行转义(在竖线前面加两个反斜杆) String[] lineArray = lineStr.split("\\|"); for (String item : lineArray) { System.out.println("line item = "+item); } }
竖线符号之因此被定为正则串的保留字符,是由于它在正则表达式里起到了“或”的判断做用,例如正则串“,| ”表示逗号和空格都是知足条件的分隔符;一个字符串若是同时包含一个逗号和一个空格,那么按照“,| ”切割的结果将是长度为3的字符串数组;也就是说,原始串被逗号分割一次后又被空格分割一次,这样一共分割两次最终获得了三个子串。下面的代码演示了使用正则串“,| ”切割字符串的效果:正则表达式
// 利用竖线同时指定多个串来分割字符串 private static void splitByMixture() { String mixtureStr = "123,456 789"; // 正则串里的竖线表示“或”,竖线左边和右边的字符均可以用来分割字符串 String[] mixtureArray = mixtureStr.split(",| "); for (String item : mixtureArray) { System.out.println("mixture item = "+item); } }
固然,正则串中的保留字符不只包括点号和竖线,还包括好些常见的符号,好比加号(+)、星号(*)、横线(-),在正则串中均需进行转义。其中加号的正则转义符为“\\+”,星号的正则转义符为“\\*”,横线的正则转义符为“\\-”。这么估摸下,加减乘除的四则运算符号,只有除法的斜杆符(/)、取余数的百分号(%)无需转义处理。假若有个字符串,要求以四则运算的五个符号进行切割,则需经过竖线把这几个转义后的字符加以链接,构成形如“\\+|\\*|\\-|/|%”的正则串。因而按照加减乘除符号切割字符串的代码就变为下面这样:数组
// 经过算术的加减乘除符号来分割字符串 private static void splitByArith() { String arithStr = "123+456*789-123/456%789"; // 正则串里的加号、星号、横线都要转义,加减乘除符号之间经过竖线隔开 String[] arithArray = arithStr.split("\\+|\\*|\\-|/|%"); for (String item : arithArray) { System.out.println("arith item = "+item); } }
分割用的正则串,不仅仅是一个个字符,还支持好几个字符组成的字符串。譬如“(1)”、“(2)”、“(3)”均可以做为分隔串,注意圆括号内部的数字能够是0到9,如此一来,从“(0)”到“(9)”的分隔串合集岂不是要写成如下这般:“(0)|(1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)”?然而以上正则串的写法有两个错误:
一、圆括号也是正则表达式的保留字符,因此不能直接在正则串中书写“(”和“)”,而必须写成转义形式“\\(”和”“\\)”。
二、做为保留字符的圆括号,其做用相似数值计算之时的圆括号,都是经过圆括号把括号内外的运算区分开。而竖线符号“|”的或运算优先级不如圆括号,所以每逢复杂一点的或运算,应当把圆括号放在整个逻辑运算式子的外面。
综合以上两点,修正以后的正则串应该改为下列形式:“\\((0|1|2|3|4|5|6|7|8|9)\\)”。但是该式子的竖线太多,意思仅仅是获取0到9之间的某个数字之一,针对这种状况,正则表达式引入了另一种简化的写法,即经过方括号包裹0123456789,形如“\\([0123456789]\\)”,一样指代0到9之间的某个数字,从而省略了若干个竖线。进一步说,平常生活中0到9,经常写作“0-9”,因而对应更简单的正则串“\\([0-9]\\)”。
其实0到9正好涵盖了全部的一位数字,对于一位数字而言,正则表达式提供了专门的表达式“\\d{1}”。式子前面的“\\d”表明某个数字,式子后面的“{1}”表明字符数量是1位。推而广之,“\\d{2}”表示两位数字,“\\d{3}”表示三位数字,等等。像这个正则例子只有一位数字,甚至尾巴的“{1}”均可以去掉,由于“\\d”默认就是一位数字。
一口气介绍了许多种从0到9的正则表达串,接下来不妨逐一验证这些正则串是否有效,验证用的代码例子以下所示:spa
// 经过圆括号及其内部数字来分割字符串 private static void splitByBracket() { String bracketStr = "(1)123;(2)456;(3)789;"; // 圆括号也是正则串的保留字符,0到9这九个数字使用竖线隔开 //String[] bracketArray = bracketStr.split("\\((0|1|2|3|4|5|6|7|8|9)\\)"); // 利用方括号汇集一群字符,表示这些字符之间是“或”的关系,故而可省略竖线 //String[] bracketArray = bracketStr.split("\\([0123456789]\\)"); // 连续的数字可以使用横线链接首尾数字,例如“0-9”表示从0到9之间的全部数字 //String[] bracketArray = bracketStr.split("\\([0-9]\\)"); // 利用“\\d”便可表达0到9的数字,后面的{1}表示1位数字,依此类推{3}表示三位数字 //String[] bracketArray = bracketStr.split("\\(\\d{1}\\)"); // “\\d”默认就是1位数字,此时后面的{1}可直接略去 String[] bracketArray = bracketStr.split("\\(\\d\\)"); for (String item : bracketArray) { System.out.println("bracket item = "+item); } }
上述的几种正则串,只能表达从“(0)”到“(9)”的分隔串,然而圆括号内部还多是两位数字或者三位数字,好比“(10)”、“(12)”、“(001)”这样。对于数字位数不固定的状况,能够把“\\d”改成“\\d+”,末尾多出来的加号,表示前面的字符容许有一位,也容许有多位。此时正则串添加了加号的字符串切割代码见下:htm
// 经过特殊符号的加号来分割字符串 private static void splitWithPlus() { String bracketStr = "(1)123;(2)456;(13)789;"; // 正则串里的加号表示能够有1到多个前面的字符 String[] bracketArray = bracketStr.split("\\(\\d+\\)"); for (String item : bracketArray) { System.out.println("plus item = "+item); } }
上面说的位数不固定,毕竟至少还有一位。假设如今某个字符不但位数不肯定,甚至还可能没有该字符(位数为0),采用写法“\\d+”就没法奏效了。要想知足位数无关紧要的状况,需将末尾的加号换成星号,也就是改为“\\d*”,此时改用星号的字符串切割代码变为下面这般:blog
// 经过特殊符号的星号来分割字符串 private static void splitWithStar() { String bracketStr = "()123;(2)456;(13)789;"; // 正则串里的星号表示能够有0到多个前面的字符 String[] bracketArray = bracketStr.split("\\(\\d*\\)"); for (String item : bracketArray) { System.out.println("star item = "+item); } }
到目前位置,分隔符还仅限于标点和数字,若是引入英文字母做为分隔串,又该如何书写呢?注意英文字母区分大小写,于是使用“a-z”表示全部的小写字母,使用“A-Z”表示全部的大写字母。若是采纳“(a)”、“(B)”、“(c)”这种大小写混合的分隔串,就得经过正则串“\\([a-zA-Z]\\)”来表达,对应的字符串切割代码以下所示:开发
// 经过大小写字母来分割字符串 private static void splitWithLetter() { String bracketStr = "(a)123;(B)456;(c)789;"; // 在正则串中表达小写字母和大写字母 String[] bracketArray = bracketStr.split("\\([a-zA-Z]\\)"); for (String item : bracketArray) { System.out.println("letter item = "+item); } }
如今有个麻烦的业务场景,圆括号内部不但多是数字和字母,还多是其它标点符号,这下难不成把众多标点符号一个个罗列出来?要知道标点符号可没有“0-9”、“a-z”、“A-Z”的简单写法噢。不过这难不倒强大的正则表达式,由于点号做为正则的保留字符,它表明了除回车\r和换行\n之外的其它字符,因此使用“\\(.\\)”便可表达符合要求的任意字符了,固然是被圆括号包裹着的、除了回车\r和换行\n之外的任意字符。下面即是匹配前述场景的字符串切割代码例子:字符串
// 经过特殊符号的点号来分割字符串 private static void splitWithDot() { String bracketStr = "(1)123;(B)456;(%)789;"; // 正则串里的点号表示除了回车\r和换行\n之外的其它字符 String[] bracketArray = bracketStr.split("\\(.\\)"); for (String item : bracketArray) { System.out.println("dot item = "+item); } }
更多Java技术文章参见《Java开发笔记(序)章节目录》get