本篇介绍String,StringBuilder和正则表达式。

String

在Java中,一般使用String来创建和操作字符串。String类即被final修饰的不可变字符串类,java中的字符串常量都是此类的实例。一般有如下两种创建方式:

  1. String str = "hello!";

JVM首先在堆中的String常量池中查找是否已存在"hello!"常量,存在则直接将新建的栈中的str引用指向此常量;不存在则先创建该常量并将其放进常量池中,使str指向此常量。

    2. String str = new String("hello!");

JVM首先在堆中的String常量池中查找是否已存在"hello!"常量,存在则在堆中创建一个对象存放此常量的引用并且将堆中对象的引用返回给栈中的str;不存在将创建该常量并将其放入常量池中,在堆中创建一个对象存放此常量的引用并且将堆中对象的引用返回给栈中的str。

String类常用方法如下:

char charAt(int index):返回指定索引的char值
boolean equals(Object obj):比较字符串内容
boolean startsWith(String prefix):判断字符串是否以指定字符串开头
boolean endsWith(String suffix) :判断字符串是否以指定字符串结尾
int length():获取字符串长度
int indexOf(String str):返回str在此字符串中的第一次出现的索引
String substring(int beginIndex):从biginIndex开始截取字符串,包括beginIndex
String substring(int beginIndex, int endIndex):从biginIndex开始截取字符串,到endIndex为止,包括beginIndex但不包括endIndex
String trim():去除两端的空格
String[] split(String str):根据给定的正则表达式分割字符串

一些方法在自己使用一次后自然就懂得怎么用了,多写代码积累代码量才是王道。

StringBuilder

由于String是不可变的,因此每次对一个字符串修改都要创建一个新的字符串对象,也就需要为新的对象分配空间。在有些对字符串修改频繁的场景中,系统开销就大了。为了解决以上问题,我们可以使用StringBuilder对象,此对象修改字符串不需要创建新的对象。

StringBuilder的许多方法与String中类似,此处我们只列出StringBuilder独有且常用的方法:

//在此字符串后面连接给定字符串,此方法为重载方法,参数可以为多个类型
public StringBuilder append(String str);
//将字符串顺序翻转
public StringBuilder reverse();

StringBuffer与StringBuilder的唯一区别在于StringBuffer是线程安全的,也因为其实现线程安全的方法是在方法前加了synchronized关键字,单线程下StringBuffer的效率要比StringBuilder低。

正则表达式

正则表达式通常被用来检索或替换符合某个模式或规则的文本。很多语言都有正则表达式,只是互相之间的语法略微有些差别。Java中的正则表达式基本语法如下表:

正则表达式语法

^

匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置

在[]中表示取反

$

匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置

.

匹配任意一个字符

?

匹配0或者1次该符号前面的字符或表达式

+

匹配1个及以上该符号前面的字符或表达式

*

匹配0个或者n个该符号前面的字符或表达式

{n}

匹配该字符前面的字符或表达式n次,其中n为非负整数

{n,}

匹配该字符前面的字符或表达式至少n次,其中n为非负整数

{n,m}

匹配该字符前面的字符或表达式至少n次,至多m次,其中n<=m

[abc]

匹配abc中的任意一个

[^abc]

匹配除abc外的任意一个

[0-9a-z]

匹配0-9,a-z的任意一个

[0-9 | a-z]

匹配0-9或a-z中的任意一个

[0-9 && 2-5]

匹配0-9且2-5中的任意一个

\d

匹配任意一个数字,等同于[0-9]

\D

匹配任意一个非数字,等同于[^0-9]

\s

匹配一个空白字符

\S

匹配一个非空白字符

\w

等同于[0-9a-zA-Z_]

\W

等同于[^0-9a-zA-Z]

正则表达式在java中需要Pattern和Matcher类的支持。Pattern是正则表达式的编译表示,以字符串表示的正则表达式必须要被编译为这个类的实例,然后才可以用来匹配,但Pattern仅支持简单的单次匹配。Matcher支持较为复杂的多次匹配。

Pattern

Pattern是某个正则表达式的编译表示,没有公共构造方法,要创建Pattern对象只能调用其静态方法compile()。

//Pattern的构造方法是私有的,通过此方法将指定的正则表达式编译成模式
static Pattern compile(String regex)
//用给定的匹配标志编译指定正则表达式
static Pattern compile(String regex, int flags)
//返回该模式的匹配标志
int flags()
//Mather的构造方法也是私有的,只有通过此方法才能得到
Mather matcher(CharSequence input) 
//返回此模式的正则表达式
String pattern()
//String类的split()方法最终调用的还是此方法
String[] split(CharSequence input)
//直接匹配字符串,但只能使用一次
static boolean matches(String regex, CharSequence input)

Matcher

Matcher是对输入的字符串进行解释和匹配操作的引擎,没有公共构造方法,要创建Matcher对象只能通过Pattern类的matcher()方法。

//对整个字符串进行匹配,全部匹配的返回true,否则返回false
boolean matches() 
//对字符串的前面部分进行匹配
boolean lookingAt() 
//对字符串进行匹配,匹配到的字符串可以在任何位置
boolean find()
//重载方法,从指定位置开始对字符串进行匹配
boolean find(int startIndex)
//返回匹配到的字符串在整个字符串索引位置
int start() 
//返回匹配到的字符串的最后一个字符在整个字符串
int end()
//返回匹配到的字符串
String group()
//重载方法,返回指定组匹配到的字符串在整个字符串索引位置
int start(int group) 
//重载方法,返回匹配到的字符串的最后一个字符在整个字符串
int end(int group)
//重载方法,返回匹配到的字符串
String group(int group)

捕获组

在Matcher类的方法中有对指定组的操作,组即捕获组。捕获组可以通过从左到右计算其开括号来编号 ,例如((a)(b(c)))如下有四个捕获组:

  • 第0组:((a)(b(c)))
  • 第1组:(a)
  • 第2组:(b(c))
  • 第三组:(c)

其中第零组总是表示整个正则表达式。

使用示例

String regex = "^(\\d+)([a-z]+)$";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher("613154dfwef");
System.out.println("find():" + m.find());
System.out.println("matches():" + m.matches());
System.out.println("lookingAt():" + m.lookingAt());
System.out.println("start():" + m.start());
System.out.println("end():" + m.end());
System.out.println("group():" + m.group());
System.out.println("以下为加入捕获组参数的匹配结果-----------");
System.out.println("捕获组个数:" + m.groupCount());
System.out.println("start1():" + m.start(1));
System.out.println("end(1):" + m.end(1));
System.out.println("group(1):" + m.group(1));
System.out.println("start(2):" + m.start(2));
System.out.println("end(2):" + m.end(2));
System.out.println("group(2):" + m.group(2));

输出结果为:

find():true
matches():true
lookingAt():true
start():0
end():11
group():613154dfwef
以下为加入捕获组参数的匹配结果-----------
捕获组个数:2
start1():0
end(1):6
group(1):613154
start(2):6
end(2):11
group(2):dfwef