JavaAPI(字符串 正则表达式)

字符串

是由若干个字符组成的一个有序的序列。在Java中,使用String这个类来描述字符串。

  1. java.lang.String 使用final修饰,不能被继承

  2. 字符串底层封装的是字符数组及其针对数组的操作方法

  3. 字符串一旦创建,对象永远无法改变,但字符串引用可以重新赋值

  4. 字符串在内存中采用Unicode编码方式,任何一个字符对应两个字节的定长编码

  5. 字符串的索引值从0开始


public class StringDemo01 {

public static void main(String[] args) {

String name = "hello"; // ['h','e','l','l','o']

String name1 = new String("hello");

String name2 = new String("hello");

System.out.println(name1 == name2);

String name3 = name+1; //hello这个对象 和1拼接后,产生了一个新的对象

System.out.println(name == name3);

}

}

字符串常量池

JVM为了提升性能和减少内存开销,避免重复创建字符串,其维护了一块特殊的内存空间,即字符串常量池

当需要使用静态字符串(字面量/常量/常量连接的结果)时,先去检查字符串常量池是否存在该字符串,若存在,则直接返回该字符串的引用地址;若不存在,则在字符串常量池中创建字符串对象,并返回对象的引用地址。

public class StringDemo02 {

public static void main(String[] args) {

String str1 = "hello";//程序启动后,常量池中是没有hello的,要将hello创建到常量池中,地址返回

String str2 = "hello"; //先去常量池中寻找是否有该样子的对象,发现是有的,因此返回常量池中的该对象的地址

System.out.println(str1 == str2); //因为两个变量指向的是同一个对象,地址一定是一样的。所以true.


String str3 = "helloworld";

String str4 = "hello" + "world"; //两个字面量做拼接操作时,javac期间会直接返回结果 "helloworld"

System.out.println(str3 == str4);//true

String str5 = str1 + "world"; // 如果是变量参与拼接运算,javac期间并不会优化,而是在运行期间拼接的。

System.out.println(str4 == str5);//false

String str6 = new String("hello");

System.out.println(str1 == str6); //false

String str7 = new String("hello");

System.out.println(str1 == str7); //false

System.out.println(str6 == str7);//false

}

}

其内存位置:

在 JDK 1.7 之前,运行时常量池(包括字符串常量池)存放在方法区。

在 JDK 1.7 时,字符串常量池被从方法区转移至 Java 堆中,注意并不是运行时常量池,而是字符串常量池被单独转移到堆,运行时常量池剩下的东西还是方法区中。

在 JDK 1.8 时,此时字符串常量池还在堆中。

常用构造器

空参构造器:

String():

初始化一个新创建的空字符序列的字符串对象

// 构建一个字符串对象,可以直接静态初始化字面量

String str1 = "helloworld";

String str2 = "";

String str3 = new String();

System.out.println(str3.equals(str2)); //true

传字节数组的构造器:

String(byte[] bs)

使用默认编码集解码byte数组,构建一个字符串对象

byte[] bts = {67, 68, 69, 70, 71, 72, 73, 74};

String s = new String(bts);

System.out.println(s);

// String(byte[] bs): 会将字节数组按照默认的字符集转成字符串。 通常默认的字符集是UTF-8.

// UTF-8字符集: 汉字是三个字节。 字母是一个。

byte[] bts2 = {-28, -72, -83, -27, -101, -67,-27, -91, -67};

String s2 = new String(bts2);

System.out.println(s2);

String(byte[] bs,String charsetName)

使用指定编码集charsetName 解码byte数组,构建一个字符串对象

byte[] bytes = {72, 101, 108, 108, 111};

String charsetName = "UTF-8";

String str = new String(bytes, charsetName);

System.out.println(str); // Output: Hello

String(byte[] bs,int offset,int length)

使用默认编码集解码byte数组的从offset开始,length个元素,构建一个字符串对象

byte[] bytes = {72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33};

String str1 = new String(bytes, 0, 5);

System.out.println(str1); // Output: Hello

String str2 = new String(bytes, 7, 5);

System.out.println(str2); // Output: World

String(byte[] bs,int offset,int length,String charsetName)

初始化一个字符串对象,使其字符序列包含参数的元素

String str3 = new String(bytes, 0, bytes.length, "UTF-8");

System.out.println(str3); // Output: Hello, World!

传字符数组的构造器

String(char[] cs)

初始化一个字符串对象,使其字符序列包含参数的元素

char[] charArray = {'H', 'e', 'l', 'l', 'o'};

String str = new String(charArray);

System.out.println(str); // Output: Hello

常用方法

length方法

length()方法可以获取字符串对象的字符个数。

一定要注意,数组的元素个数的获取方式是 引用.length, 不是方法,是属性

String obj = "你好,HelloWorld";

System.out.println(obj.length()); //13

indexOf方法实现检索

String类型提供了几个重载的indexOf方法

int indexOf(String str)

int indexOf(String str,int fromIndex)

作用:用于返回指定字符串在此字符串中第一次出现的索引,找不到返回-1


String还定义了lastIndexOf方法

int lastIndexOf(String str)

int lastIndexOf(String str,int endIndex)//从0处开始向后找到指定位置

作用:用于返回指定字符串在此字符串中最后一次出现的索引,找不到返回-1


String line = "no zuo no die";

System.out.println("line的长度是:"+line.length());

//获取zuo在line的哪个位置上,从0开始

int i = line.indexOf("zuo");

System.out.println("出现的位置:"+i);

int i1 = line.indexOf("o", 3);

System.out.println(i1);

int i2 = line.indexOf('S', 3);

System.out.println(i2);

System.out.println("o最后一次出现的位置:"+line.lastIndexOf('o',6));

使用substring获取子串

常用重载方法:

String substring(int beginIndex)

String substring(int beginIndex,int endIndex)

作用:substring方法用于返回一个字符串的子字符串


// 获取"zuo no"

String sub1 = line.substring(3, 9);

System.out.println("获取的子串:"+sub1);

sub1 = line.substring(7);

System.out.println("获取的子串:"+sub1);

trim截掉空格

String trim()

作用:去掉一个字符串的前与后的空字符,不会去掉中间的空字符


line = " hello kitty ";

System.out.println("line的长度:"+line.length());

System.out.println(line.trim());

charAt获取字符

char charAt(int index)

作用:返回指定索引处的char值


//获取索引3处的字符

char c = line.charAt(3);

System.out.println("c:"+c);

startsWith和endsWith

boolean startsWith(String str)

boolean endsWith(String str)

作用:检查一个字符是否以指定的字符串为前缀或后缀


//判断line是不是一个网址:

System.out.println("line是否为一个网址:"+line.startsWith("http://"));

line = "http://www.baidu.com";

System.out.println("line是否为一个网址:"+line.startsWith("http://"));

//查看字符串是否为一个qq邮箱

System.out.println("line是否为一个网址:"+line.endsWith("qq.com"));

line = "mmforu@qq.com";

System.out.println("line是否为一个网址:"+line.endsWith("qq.com"));

大小写变换

String toUpperCase()

String toLowerCase()

作用:对字符串中的字母进行转换成全部大写或全部小写


line = "AbcDefG";

String upperCase = line.toUpperCase();

System.out.println(upperCase);

String lowerCase = line.toLowerCase();

System.out.println(lowerCase);

toCharArray

char[] toCharArray()

作用: 将字符串转变成字符数组


line = "hello"; // ['h','e']

char[] charArray = line.toCharArray();

System.out.println(Arrays.toString(charArray));

valueOf

static String valueOf(int value)

static String valueOf(double d)

static String valueOf(char[] ch)

static String valueOf(Object obj)

作用:将其他类型转换成字符串类型


//将 int类型的1001, 转成字符串"1001" 3.14转成字符串"3.14" {'h','e'} 转成字符串 "he"

int age = 1001;

String s = String.valueOf(age);

String s1 = String.valueOf(3.14);

String s2 = String.valueOf(new char[]{'h', 'e'});

System.out.println(s+","+s1+","+s2);

equals与==

字符串类型中也重写了equals方法,用来比较两个字符串的相同位置上的内容是否相同,有一个不一致就直接返回false

boolean equals(String str)

  • equals方法用于判断两个字符串的内容是否一样
  • ==用于判断两个字符串是不是同一个对象(用来比较两个变量里的地址是否相同 )

//用户输入的用户名

String username = "zhangsan";

//模拟从数据库中获取的用户名

String user = new String("zhangsan");

//需要校验两个名字是否相同

System.out.println(username.equals(user));

StringBuilder和StringBuffer

String类型,如果频繁的拼接,会造成大量的垃圾对象,因为对象是不可变的,拼接操作会产生新对象。

可以使用其他的某些类,来实现高效率的字符串的操作:StringBuilder和StringBuffer。

StringBuilder和StringBuffer,都是一个可变的字符序列(即可变的字符串),对象创建后可以通过调用方法来实现字符序列的改变,StringBuilder和StringBuffer类中的方法完全相同。

区别:

StringBuilder是线程不安全的,效率高

StringBuffer是线程安全的,效率低

常用构造器

StringBuilder()

构造一个不带任何字符的字符串生成器,其初始容量为16个字符

可变字符串类型StringBuilder类型


StringBuilder builder = new StringBuilder();

StringBuilder(String str)

构造一个字符串生成器,其初始化为指定的字符串内容


StringBuilder bs = new StringBuilder("baidu");

常用方法

append方法

StringBuilder append(boolean b)

StringBuilder append(String str)

可以连续调用

作用:将指定字符串追加到字符串之后


StringBuilder a = builder.append("中国");

System.out.println(a);

//追加"是伟大的"

builder.append("是伟大的");

System.out.println(builder);

builder.append("国家").append(",是世界上").append("文明最悠久的").append("国家");

System.out.println(builder);

insert方法

StringBuilder insert(int index,String str)

作用:将指定字符串插入到字符串的指定索引处


StringBuilder bs = new StringBuilder("baidu");

bs.insert(0,"www.");

System.out.println(bs);

bs.append(".com").insert(bs.length(),".cn");

System.out.println(bs); // www.baidu.com.cn

delete方法

StringBuilder delete(int start , int end)//包前不包后

作用:删除字符串中的一部分


bs.delete(10,13);

System.out.println(bs);

bs.delete(3,4).delete(8,10);

System.out.println(bs);

reverse方法

StringBuilder reverse()

作用:将字符序列进行反转(左右颠倒)


bs.reverse();

System.out.println(bs);

String result = bs.toString();

System.out.println(result);

toString方法

String toString()

作用:将StringBuilder对象转变成String对象


String a1 ="hello";

String b1 = "world";

String c1 = a1+b1;

System.out.println(c1);

三者区别

  • StringBuilder是可变字符串,如果进行字符串的内容计算,建议选择StringBuilder,这样性能更好一些。

  • java的字符串连接的过程是利用StringBuilder实现的

  • StringBuilder 也是final修饰的类型,不能被继承

  • StringBuilder没有重写equals方法

  • StringBuilder是非线程安全的,并发处理,性能稍快

  • StringBuffer是线程安全的,同步处理,性能稍慢

正则表达式

**正则表达式(Regular Expressions),是一个特殊的字符串,可以对普通的字符串进行校验检测等工作。**正则表达式不是Java特有的,它是一套独立的语法,可以在java,c++,python等语言中使用。

正则表达式,最基本的使用场景是用来做校验,校验一个字符串是否满足预设的规则。在校验的基础 上,又添加了若干个其他的引用场景,例如: 批量的查找、替换、切割...

基本语法:

字符串集合

[] : 表示匹配括号里的任意一个字符。

[abc] :匹配a 或者 b 或者 c

//boolean matches(String regex):

//用来检验this是否符合regex这个正则表达式

//返回true符合 反之不符合

[^abc] : 匹配任意一个字符,只要不是a,或b,或c 就表示匹配成功

[a-z] : 表示匹配所有的小写字母的任意一个。

[A-Za-z] :表示匹配所有的小写字母和大写字母的任意一个。

[a-zA-Z0-9]:表示匹配所有的小写字母和大写字母和数字的任意一个。

[a-z&&[^bc]] :表示匹配所有的小写字母除了b和c, 只要匹配上就是true.

预定义字符集

转义字符:在编程语言中,有一些符合比较特殊,不会被编译语言当初普通字符来使用,如果非要当成普通字符来使用,必须在其前面添加一个反斜杠

\d: 用于匹配数字字符中的任意一个 相当于[0-9]

\w: 匹配单词字符中的任意一个 单词字符就是[a-zA-Z0-9_]

\D: 用于匹配非数字字符中的任意一个 相当于[^0-9]

\W: 用于匹配非单词字符中的任意一个

\s: 用于匹配空格,制表符(\t),退格符(\b),换行符(\n)等中的任意一个

\S: 用于匹配非空格,制表符,退格符,换行符等中的任意一个

. : 用于匹配任意一个字符(不需要转义)


java 复制代码
 public static void main(String[] args) {
        //使用正则表达式语法,来定义一个规则
        String regex = "[abc]";
        String line = "ab";
        /**
         *  boolean  matches(String regex):
         *  用来检验this是否符合regex这个正则表达式。
         *  返回true,表示符合。 false表示不符合
         */
        if(line.matches(regex)){
            System.out.println("符合规则");
        }else{
            System.out.println("不符合规则");
        }

        regex = "[a-zA-Z0-9]";
        System.out.println("_".matches(regex));
        //验证:用户不能输入敏感字 X,中,国
        regex = "[^X中国]";
        System.out.println("中".matches(regex));

        //验证: 用户只能输入A-Z,0-9,但是不能输入里面的W,X,5,8
        regex = "[A-Z0-9&&[^WX58]]";
        System.out.println("C".matches(regex));

        System.out.println("-----------------预定义字符集----------------------");
        //转义字符:  在编程语言中,有一些符合比较特殊,不会被编译语言当成普通字符来使用,如果非要当成普通字符来使用,必须在其前面添加一个反斜杠
        //          这个反斜杠,我们称之为转义字符。
        regex = "\\d";
        System.out.println("a".matches(regex));
        regex = "\\D";
        System.out.println("a".matches(regex));
        regex = "\\w";
        System.out.println("-".matches(regex));
        regex = "\\W";
        System.out.println("-".matches(regex));
        /**
         *   \t:   制表符
         *   \n:   换行符
         *   \r:   回车符
         *   \b:  退格符
         */
        regex = "\\s";
        System.out.println("\t".matches(regex));
        regex = "\\S";
        System.out.println("+".matches(regex));
        regex = "."; // 注意: 表示任意字符时  点不需要转义,如果需要使用普通字符串点,需要添加转义字符
        System.out.println("a".matches(regex));


    }

数量词

X? :匹配0个或1个 [a]? a可有可无

X* :匹配0个或1个以上

x+ :匹配1个以上

X{n} :匹配n个

X{m,}:匹配m个以上 [\\w]{5,} 5个以上的单词字符

X{m,n}:匹配m~n个


java 复制代码
public static void main(String[] args) {
        //规则:a这个字符可有可无
        String regex = "[a]?";
        System.out.println("".matches(regex));  //true
        System.out.println("a".matches(regex)); //true
        System.out.println("b".matches(regex)); //false
        regex = "[a]?b";
        System.out.println("ab".matches(regex));
        System.out.println("b".matches(regex));
        regex = "abc";
        System.out.println("xxx".matches(regex));//false
        System.out.println("ab".matches(regex)); //false
        System.out.println("abc".matches(regex)); //true
        regex = "[a-z][a-z]";
        System.out.println("xy".matches(regex)); //true
        //注册的名字是6个单词字符
        regex = "[\\w][\\w][\\w][\\w][\\w][\\w]";
        System.out.println("hello1".matches(regex)); //true
        regex = "[\\w]*";
        System.out.println("hello1".matches(regex));
        regex = "[\\w]+";
        System.out.println("a".matches(regex));
        regex = "[\\w]{5}";
        System.out.println("hello1".matches(regex));//false
        System.out.println("abcde".matches(regex)); //true
        regex = "[\\w]{5,}";
        System.out.println("hello1".matches(regex));//true
        //用户名可以使用5~8个单词字符
        regex = "[\\w]{5,8}";
        System.out.println("zhangsan".matches(regex));//true
        System.out.println("zhang+".matches(regex));//false
    }

分组()

想要检验的普通字符串可能符合某一个要求,或者是另外一个要求,此时

正则表达式需要使用分组符号(),来表示这些规则

在正则表达式上可以使用()来进行对一些字符分组,并可以使用逻辑运算符|来进行选择匹配

()里是成员,成员之间使用 或 来连接

reg:

String regex = "(135|137)[\\d]{8}" //匹配手机号是135或者是137开头的


java 复制代码
   public static void main(String[] args) {
        //要求: 客户输入的手机号必须是137,158,182开头的手机号
        String regex = "1(37|58|82)\\d{8}";
        System.out.println("18211112222".matches(regex));
        //要求: 判断客户输入的是不是一个网址  www.baidu.com
        String regexAddress = "(http[s]?://)?www\\.[\\w]+(\\.(com|cn|net))+";
        String address = "www.baidu.com";
        if(address.matches(regexAddress)){
            System.out.println("是一个网址");
        }else{
            System.out.println("不是一个网址");
        }
    }

^和$

^:表示严格从头匹配

$: 表示匹配到结尾

Java语言底层默认使用^开头,并且是$结尾的,即严格从头到尾进行校验


java 复制代码
  public static void main(String[] args) {
        String regex = "[abc]{5,8}$";
        String line = "xabbbbb";
        System.out.println(line.matches(regex)); //底层在正则表达式前添加了^
    }

常用方法

  1. boolean matches(String regex)

判断this字符串是否匹配正则表达式regex

  1. String[] split(String regex)

对this使用匹配上正则表达式的子串 进行切分 成字符串数组

  1. replaceAll()

替换 前面写旧的 后面写新的

//去掉字符串中的空格,使用空字符串替换调空格部分


public static void main(String[] args) {

String line = "no zuo no die ";

String regex = " ";

String[] split = line.split(regex);

System.out.println(Arrays.toString(split));

for (int i = 0; i < split.length; i++) {

System.out.println(split[i].length());

}

// 去掉字符串中的空格。使用空字符串替换掉符合正则表达式的子串部分

String s = line.replaceAll("[ ]+", "");

System.out.println(s);

}

相关推荐
阿华的代码王国1 小时前
【从0做项目】Java搜索引擎(6)& 正则表达式鲨疯了&优化正文解析
java·后端·搜索引擎·正则表达式·java项目·从0到1做项目
程序员小王꧔ꦿ13 小时前
BeautifulSoup、lxml/XPath和正则表达式在数据爬取中的核心差异及适用场景
正则表达式·beautifulsoup
程序员小王꧔ꦿ13 小时前
BeautifulSoup、lxml/XPath和正则表达式在数据爬取中的适用场景
正则表达式·beautifulsoup
时之彼岸Φ2 天前
文本操作基础知识:正则表达式
正则表达式
Dontla3 天前
正则化(Regularization)和正则表达式(Regular Expression)区别
正则表达式
索然无味io3 天前
Python--正则表达式
开发语言·windows·python·安全·web安全·网络安全·正则表达式
Sun_Weiss3 天前
从字符串中匹配多个关键词,优先匹配更长的关键词
python·正则表达式·字符串
哒啵Q2975 天前
对正则表达式说不!!!
正则表达式
玖龍的意志6 天前
正则表达式(Regular expresssion)
python·正则表达式