1 字符串的基本特性

1.1 不可变性

字符串本身是一个对象,具有不可变性,对其进行的修改值操作都是创建一个新的字符串对象。以包含修改后内容的字符串,而原始字符串对象的内容不变。
任何指向该对象的引用都不能改变其值。

2 字符串的操作

2.1 String的+、+=

Java中对String对象只有+、+=两个符号进行了重载。编译器在编译Java代码的时候,自动引入了StringBuilder类,StringBuilder实现了一个append()方法,经过四次调用可以将多个String类型对象内容拼接起来,最后通过toString()方法,一次性产生新的String对象。

  1. StringBuilder.append();//
  2. StringBuilder.toString();//
  3. StringBuilder.insert();//
  4. StringBuilder.repleace();//
  5. StringBuilder.substring();//
  6. StringBuilder.reverse();//
  7. StringBuilder.delete();//

StringBuilderJava SE5引入的,不具有线程安全,而此前用的是StringBuffer,具有线程安全。

2.2 基本方法

2.2.1 增

(1)构造器

  1. String.String();//
  2. String.String(String s);//
  3. String.String(StringBuilder s);//
  4. String.String(StringBuffer s);//
  5. String.String(char[] s);//
  6. String.String(byte[] s);//

(2)生成字符数组,部分字符串——使用索引

  1. String.getChars(int begin, int end);
  2. String.getBytes(int begin, int end);

(3)生成字符数组,完整的字符串

  1. String.toCharArray();//

(4)截取字符串

  1. String.substring(int begin);//子字符串
  2. String.substring(int begin, int end);//子字符串

(5)将一个基本数据类型转换成String

  1. 1String.valueOf(boolean b) : boolean 变量 b 转换成字符串
  2. 2String.valueOf(char c) : char 变量 c 转换成字符串
  3. 3String.valueOf(char[] data) : char 数组 data 转换成字符串
  4. 4String.valueOf(char[] data, int offset, int count) : char 数组 data data[offset] 开始取 count 个元素 转换成字符串
  5. 5String.valueOf(double d) : double 变量 d 转换成字符串
  6. 6String.valueOf(float f) : float 变量 f 转换成字符串
  7. 7String.valueOf(int i) : int 变量 i 转换成字符串
  8. 8String.valueOf(long l) : long 变量 l 转换成字符串
  9. 9String.valueOf(Object obj) : obj 对象转换成 字符串, 等于 obj.toString()

(6)生成一个且仅生成一个字符串引用

  1. String.intern();//若常量池没有该字符串则将该字符串的引用放入常量池并返回该引用,若常量池存在该字符串则直接返回该常量池字符串的引用。

2.2.2 删

2.2.3 改

(1)连接字符串

  1. String.concat(String s);//字符串拼接。返回值为新的字符串

(2)替换字符或字符串

  1. String.replace(char oldc || CharSequence oldc, char newc || CharSequence newc);//替换字符||字符串,返回新的字符串

(3)转换大小写

  1. String.toLowerCase();//转大写
  2. String.toUpperCase();//转小写

(4)消除两端空白字符

  1. String.trim();//

2.2.4 查

(1)字符串长度——字符个数

  1. String.length();

(2)查看字符——使用索引

  1. String.charAt(int i);

(3)比较字符串

  1. String.equals(String s);//比较每一个字符是否相同
  2. String.equalsIgnoreCase(String s);//比较每一个字符是否相同,忽略大小写
  3. String.==;//比较字符串是否是同一个对象的引用
  4. String.compareTo(String s);//这个函数的作用就是对两个字符串按字典排序的方式进行比较,返回两个字符串中第一个不同的字符的ascII码差值。
  5. String.contentEquals(CharSequence s||StringBuffer s);//比较,字符内容完全一致返回true
  6. String.regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len);//区域比较。本String在toffset位置开始,与other在ooffset位置开始,之后len长度的字符是否相同。

(4)搜索字符序列

  1. String.contain(CharSequence s);//判断字符串str中是否有子字符串。如果有则返回true,如果没有则返回false。CharSequence包含String、char[]
  2. public boolean startsWith(String prefix, int toffset) || public boolean startsWith(String prefix);//prefix字符串是否是本字符串的前缀,toffset为开始位置索引,默认为字符串开始位置。
  3. public boolean endsWith(String suffix);//suffix字符串是否是本字符串的后缀
  4. String.indexOf(char c || char c, int begin || String s || String s, int begin);//查询c或s的索引下标,begin表示开始查找的位置。从前向后。
  5. String.lastIndexOf(char c || String s);//查询c或s的索引下标,从后向前。

3 字符串输入

早期也是用过BufferReader.readLine()之类的方法,功能较为简单,效果一般,实现复杂功能较为困难。

3.1 Scanner界定符

Scanner scanner = new Scanner();

  1. Scanner.nextLine();//输入一行
  2. Scanner.nextInt();//输入正数
  3. Scanner.hasNextInt();//检查是否出现界定符
  4. 设置界定符
  5. Scanner.useDelimiter("\\s*,\\s*");//以逗号,作为界定符;默认情况下,不自行设置的界定符为空白字符。
  6. Scanner.delimiter();//返回正在使用的界定符Pattern对象。

3.2 用正则表达式扫描

同样需要使用Scanner对象。Scanner scanner = new Scanner(String s);

  1. String pattern = "";
  2. Scanner.next(pattern);//按照pattern中定义的正则表达式扫描
  3. Scanner.hasNext(pattern);//按照pattern中定义的正则表达式判断是否还有后续
  4. MatchResult match = sacnner.match();//使用MatchResult对象存储匹配完成的数据。
  5. String s1 = match.group(1);
  6. String s2 = match.group(2);

3.3 早期分割字符串方法——StringTokenizer

基本废弃。

4 字符串格式化输出

4.1 printf()

类似于C语言的printf函数,采用占位符的方法表示数据的位置。这些占位符又称格式修饰符。
常用占位符:

%d 整数(十进制)占位符
%x 整数(十六进制)占位符
%f 浮点数(十进制)占位符
%e 浮点数(科学计数)占位符
%s 字符串
%c Unicode字符
%b Boolean值,结果为true||false,其他类型转换为Boolean时,只要不为null,都为true
%h 散列码

样例如下所示:

  1. System.out.printf("Row 1 : [%d %f]", x, y);//x为正数,y为浮点数

4.2 System.out.format()

仿照printf设计了format方法,用法相同。

  1. System.out.format("Row 1 : [%d %f]", x, y);//x为正数,y为浮点数

4.3 Formatter类

4.3.1 定义

Java中设计了java.util.Formatter类用于处理格式化功能。

  1. Formatter f = new Formatter(System.out);
  2. int x = 5;
  3. float y = 8.2;
  4. f.format("Row 1 : [%d %f]", x, y);//x为正数,y为浮点数
  5. 输出即为:
  6. Row 1 : [5 8.2]

4.3.2 格式化说明符

用于控制更加精细的格式化输出。抽象语法如下:

  1. %[argument_index$][flags][width][.precision]conversion
  • width:控制整个域的最小尺寸。所有数据类型转换时都支持width
  • 默认右对齐,通过符号-可以改变对齐方式。
  • precision:控制整个域最大尺寸。并不是所有数据类型都支持precision。应用于字符串类型时表示字符最大数量;应用于浮点数时表示默认的小数位数,多舍少补零;无法用于正数。

  • 4.4 String.format()

    接受参数与Formatter.format()一致,但是返回值是一个String对象。

    5 正则表达式

    这是一种文本处理工具。一种完全通用的字符串处理方式,能够解决匹配、选择、编辑和验证。

    5.1 基础

  • Java中,**\\**双反斜杠与其他语言不同,代表要插入一个正则表达式的反斜杠。如果想插入正常的反斜杠使用\\\\。此外换行符和制表符还是使用单个反斜杠\n\t

  • 当表达一个或多个之前已经写过的表达式时,使用+表示,若想表示正常加法,则用\\+。负号还是-
  • 括号()正则表达式中有分组作用
  • 竖直线|表示操作
  • 若想表示一个-+或都没有,可以再括号之外加一个?表示二者皆没有。
  • \W表示非单词字符,\w表示一个单词字符。这功能用于:

    1. String.split("\\W+");//按照多个非单词字符分割
    2. String.split("\\w+");//按照多个单词字符分割
  • 正则表达式在字符串中主要用于匹配、分割和替换。

    5.2 正则表达式语法

    5.2.1 字符、字符类

    (1)字符

ABC 指定字符
\xhh 十六进制为0xhh的字符
\uhhhh 十六进制为0xhhhh的Unicode字符
\t 制表符
\n 换行符
\r 回车
\f 换页
\e 转义

(2)字符类

. 任意一个字符
[abc] a|b|c
[^abc] 出了a|b|c以外任意一个字符
[a-zA-Z] a-zA-Z中的任意一个字符
[abc[hij]] 相当于[abchij]
[a-z&&[hij]] a-z之间且h|i|j中任意一个
\s 空白符(空格、tab、换行、换页和回车)
\S 非空白符
\d 数字
\D 非数字
\w 词字符(a-z A-Z 0-9)
\W 非词字符

5.2.2逻辑操作符

XY Y在X后面
X|Y X或Y
(X) 捕获组,括号内为一组

5.2.3 边界匹配符

^ 一行起始
& 一行结束
\b 词边界
\B 非词边界
\G 前一个匹配的结束

5.2.4 量词

量词具有三种类型:贪婪型、勉强型、占有型。使用时必须搭配括号(),如:abc+,想表示匹配一个或多个abc,这是错误的,正确的写法应该是(abc)+

贪婪(尽可能多的匹配) 勉强(尽可能少的匹配) 占有(防止匹配失败时回溯,不保存中间状态) 匹配规则
X? X?? X?+ 一个或0个X
X* X*? X*+ 0个或多个X
X+ X+? X++ 一个或多个X
X{n} X{n}? X{n}+ 恰好n次X
X{n,} X{n,}? X{n,}+ 至少n次X
X{n,m} X{n,m}? X{n,m}+ X至少n次,且不超过m次

5.3 匹配——Pattern和Matcher

  1. Pattern.compile(String pattern);//加载pattern表达式
  2. Matcher.matcher();//按照pattern表达式匹配整个字符串
  3. Pattern.matcher(String s);//按照pattern表达式匹配整个字符串s
  4. Matcher.lookingAt();//按照pattern表达式匹配字符串初始位置
  5. Matcher.find();//像迭代器一个,遍历匹配整个字符串,配合Pattern.group()获取匹配结果
  6. Matcher.find(int begin);//同find(),增加了一个起始位置参数begin
  7. Matcher.groupCount();//Matcher.find()匹配结果的组的个数
  8. Matcher.group(int i);//Matcher.find()匹配结果的组内容,按照参数i获取第i组的内容。
  9. Matcher.start(int i);//第i组的起始索引
  10. Matcher.end(int i);//第i组的结束索引

5.4 分割——split

  1. Pattern.compile(String pattern).split(String s);//按照pattern表达式分割s
  2. Pattern.compile(String pattern).split(String s, int limit);//按照pattern表达式分割s,且只分割成limit份

5.5 替换——replace

  1. String.replaceAll(String replacement);//以replacement替换String里匹配到的内容
  2. String.replaceFirst(String replacement);//以replacement替换String里第一次匹配到的内容
  3. String.replaceAll(String pattern, String replacement);//以replacement替换String里匹配到的内容,按照pattern表达式匹配
  4. String.replaceFirst(String pattern, String replacement);//以replacement替换String里第一次匹配到的内容,按照pattern表达式匹配

5.6 复用——reset

  1. Matcher.reset(String news);//将已有的Matcher用于新的String对象news
  2. Matcher.reset();//将已有的Matcher匹配状态,重置到字符序列起始位置

5.7 正则表达式与Java I/O

Java I/O读取的文件内容进行字符串搜索匹配操作。