关于java的字符串

来源:互联网 发布:js请求servlet 编辑:程序博客网 时间:2024/06/02 16:44
1.String对象是不可变的!
String类中任何看似修改字符串的方法其实都是重新创建一个新的string对象,
2.String的“+”与StringBuilder
“+”和“+=”在字符串里是被重载过得,专门为字符串拼接用,也是唯一的两个被重载过得操作符。
+底层实现其实是StringBuilder,一个加号表示用了一个StringBuilder对象,java SE5之前是StringBuffer,区别在于StringBuffer是线程安全的。
3.无意识递归
指java编程中,所有类都有一个toString()方法,当你打印这个类时,实际执行的是这么一句话:类名+this,这里this会自动类型转换成String,怎么转换?就是调用this上的toString方法,于是就发生递归调用,如果想打印内存地址,应该调用Object.toString()方法。
4.String上的操作
charAt(3),取String上索引为3的字符(char类型)。
concat(”aaa“),与字符串”aaa“相连,返回一个新的String对象。
replace(“a”,“b”),将字符串中所有a替换为b
trim(),将String两端的空白字符删除,返回新的String对象,如果未改变,返回原始String对象
5.格式化输出
System.out.printf("%d---%d",x,y);
System.out.format("[%d %d]",x,y);
d表示整数、s表示字符串、f表示小数
上面这两段代码中的x,y必须都是整数才行,不然会报错的。输出格式为:[x,y]
5.1Formatter类
这是一个翻译器,它将 你的格式化字符串和数据 翻译成需要的结果。
需要
Formatter f=new Formatter(System.out);
f.format("%s lalalala (%d,%d))\n ","bbb",2,3);
创建Formatter 需要传递一些信息,告诉它结果输出向哪,当然,有时候也不需要,如下面
Formatter f=new Formatter();
String s=f.format("%s lalalala (%d,%d))\n ","bbb",2,3).toString();
System.out.println(s);
6.正则表达式

字符 
x 字符 x 
\\ 反斜线字符 
\0n 带有八进制值 0 的字符 n (0 <= n <= 7) 
\0nn 带有八进制值 0 的字符 nn (0 <= n <= 7) 
\0mnn 带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7) 
\xhh 带有十六进制值 0x 的字符 hh 
\uhhhh 带有十六进制值 0x 的字符 hhhh 
\t 制表符 ('\u0009') 
\n 新行(换行)符 ('\u000A') 
\r 回车符 ('\u000D') 
\f 换页符 ('\u000C') 
\a 报警 (bell) 符 ('\u0007') 
\e 转义符 ('\u001B') 
\cx 对应于 x 的控制符 
  字符类 
[abc] a、b 或 c(简单类) 
[^abc] 任何字符,除了 a、b 或 c(否定) 
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围) 
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集) 
[a-z&&[def]] d、e 或 f(交集) 
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去) 
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去) 
  预定义字符类 
. 任何字符(与行结束符可能匹配也可能不匹配) 
\d 数字: [0-9] 
\D 非数字: [^0-9] 
\s 空白字符: [ \t\n\x0B\f\r] 
\S 非空白字符:[^\s] 
\w 单词字符: [a-zA-Z_0-9] 
\W 非单词字符:[^\w] 
  POSIX 字符类(仅 US-ASCII) 
\p{Lower} 小写字母字符:[a-z] 
\p{Upper} 大写字母字符:[A-Z] 
\p{ASCII} 所有 ASCII:[\x00-\x7F] 
\p{Alpha} 字母字符:[\p{Lower}\p{Upper}] 
\p{Digit} 十进制数字:[0-9] 
\p{Alnum} 字母数字字符:[\p{Alpha}\p{Digit}] 
\p{Punct} 标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ 
\p{Graph} 可见字符:[\p{Alnum}\p{Punct}] 
\p{Print} 可打印字符:[\p{Graph}\x20] 
\p{Blank} 空格或制表符:[ \t] 
\p{Cntrl} 控制字符:[\x00-\x1F\x7F] 
\p{XDigit} 十六进制数字:[0-9a-fA-F] 
\p{Space} 空白字符:[ \t\n\x0B\f\r] 
java.lang.Character 类(简单的 java 字符类型) 
\p{javaLowerCase} 等效于 java.lang.Character.isLowerCase() 
\p{javaUpperCase} 等效于 java.lang.Character.isUpperCase() 
\p{javaWhitespace} 等效于 java.lang.Character.isWhitespace() 
\p{javaMirrored} 等效于 java.lang.Character.isMirrored() 
Unicode 块和类别的类 
\p{InGreek} Greek 块(简单块)中的字符 
\p{Lu} 大写字母(简单类别) 
\p{Sc} 货币符号 
\P{InGreek} 所有字符,Greek 块中的除外(否定) 
[\p{L}&&[^\p{Lu}]] 所有字母,大写字母除外(减去) 
边界匹配器 
^ 行的开头 
$ 行的结尾 
\b 单词边界 
\B 非单词边界 
\A 输入的开头 
\G 上一个匹配的结尾 
\Z 输入的结尾,仅用于最后的结束符(如果有的话) 
\z 输入的结尾 
Greedy 数量词 
X? X,一次或一次也没有 
X* X,零次或多次 
X+ X,一次或多次 
X{n} X,恰好 n 次 
X{n,} X,至少 n 次 
X{n,m} X,至少 n 次,但是不超过 m 次 
Reluctant 数量词 
X?? X,一次或一次也没有 
X*? X,零次或多次 
X+? X,一次或多次 
X{n}? X,恰好 n 次 
X{n,}? X,至少 n 次 
X{n,m}? X,至少 n 次,但是不超过 m 次 
Possessive 数量词 
X?+ X,一次或一次也没有 
X*+ X,零次或多次 
X++ X,一次或多次 
X{n}+ X,恰好 n 次 
X{n,}+ X,至少 n 次 
X{n,m}+ X,至少 n 次,但是不超过 m 次 
Logical 运算符 
XY X 后跟 Y 
X|Y X 或 Y 
(X) X,作为捕获组 
Back 引用 
\n 任何匹配的 nth 捕获组 
引用 
\ Nothing,但是引用以下字符 
\Q Nothing,但是引用所有字符,直到 \E 
\E Nothing,但是结束从 \Q 开始的引用 
特殊构造(非捕获) 
(?:X) X,作为非捕获组 
(?idmsux-idmsux) Nothing,但是将匹配标志i d m s u x on - off 
(?idmsux-idmsux:X) X,作为带有给定标志 i d m s u x on - off 
的非捕获组 (?=X) X,通过零宽度的正 lookahead 
(?!X) X,通过零宽度的负 lookahead 
(?<=X) X,通过零宽度的正 lookbehind 
(?<!X) X,通过零宽度的负 lookbehind 
(?>X) X,作为独立的非捕获组
6.1String的正则表达式
检查String是否满足正则表达式,有一个简单的用法:
System.out.println("234".matches("-?\\d+"));
这句话的意思是,可能有一个或没有负号 后面跟着一个或多个数字
这里\\表示,我想在正则表达式里插入普通的字面上的反斜杠\,不给他特殊意义。
System.out.println("+234".matches("(-|\\+)?\\d+"));
(-|\\+)?这里表示可能有 -或+,也可能什么都没有,这里\\+,因为字符+在正则有特殊含义,所以需要用\\转义字符,转成普通字符加号
练习一个邮箱的正则:
规则:以字母或数字或下划线或 - 开头,可能有多位,再往后必须要有@,字母或数字或下划线或 -([2~5]位),。(点号),结尾是2~5个字母
System.out.println("4422paPA@123.com".matches("^([a-zA-Z0-9-_])+@([a-zA-Z0-9-_]{2,5}).[a-zA-Z]{2,5}$"));
String的正则切割
String s="ab1c+d3ef-g7hij_5kl_m9n baba";
以数字切割:System.out.println(Arrays.asList(s.split("\\d")));
以非单词字符切割:System.out.println(Arrays.asList(s.split("\\W+")));
String的正则替换
String s="abc aba acd,opq,lol,ppq";
替换第一个匹配的:System.out.println(s.replaceFirst("a\\w+","haha"));
替换所有匹配的:System.out.println(s.replaceAll("a\\w+","haha"));
输出结果: haha aba acd,opq,lol,ppq
haha haha haha,opq,lol,ppq
6.2创建正则表达式:
Pattern和Matcher
String s="abc aba acd,opq,lol,ppq";
Pattern p=Pattern.compile("[a-z, ]+");
Matcher m=p.matcher(s);
System.out.println(m.matches());结果:true

Matcher的一些方法运用:
find和group
Pattern p=Pattern.compile("\\w+");
Matcher m=p.matcher(s);
while (m.find()){
    System.out.print(" "+m.group());
}abc aba acd opq lol ppq
groupCount和group(int)
Pattern p = Pattern.compile("\\w+");
Matcher m = p.matcher(s);
while (m.find()) {
    for (int i = 0; i <= m.groupCount(); i++) {
        System.out.print(m.group(i)+" ");
    }
}abc aba acd opq lol ppq
start和end
String s = "abc(两个空格)aba acd,opq,lol,ppq";
Pattern p = Pattern.compile("\\w+");
Matcher m = p.matcher(s);
while (m.find()) {
    System.out.println("data:"+m.group()+";start:"+m.start()+";end:"+m.end());
}data:abc;start:0;end:3
data:aba;start:5;end:8
data:acd;start:9;end:12
data:opq;start:13;end:16
data:lol;start:17;end:20
data:ppq;start:21;end:24
lookingAt()
String s = "abc aba acd,opq,lol,ppq";
Pattern p = Pattern.compile("\\w");
Matcher m = p.matcher(s);
System.out.println(m.lookingAt());true
Pattern标记,CASE_INSENSITIVE表示不在乎大小写,Pattern.MULTILINE表示多行模式下匹配
COMMENTS忽视空格忽略注释。
Pattern p = Pattern.compile("^java",Pattern.CASE_INSENSITIVE|Pattern.MULTILINE);
String s = "java has regex\nJava has regx\nJAVA has pretty\nlalla in Java";
Matcher m=p.matcher(s);
while (m.find()){
    System.out.println(m.group());
}java
Java
JAVA
Split,断开边界由正则表达式确定
String s = "abc!!aba!!acd!!opq!!haha";
String[] st = Pattern.compile("!!").split(s);
System.out.println(Arrays.toString(st));
String[] st1 = Pattern.compile("!!").split(s,3);
System.out.println(Arrays.toString(st1));[abc, aba, acd, opq, haha]
[abc, aba, acd!!opq!!haha]
替换操作,
之前说string.replaceFirst()和string.replaceAll(),现在appendReplacement(StringBuffer sb,String replacement)执行渐进式替换,允许你调用其他方法来生成或处理replacement,使你能用编程的方式将目标分隔成组,从而具备更强大的替换功能。
String s=" aaasf. hsfhuf ijdigju,ihuih chbcjx ch\n" +
        " dew.yhgy ehdywhf uila ej,lk dfn,jk\n" +
        " leh ruiae, hui, lfhl kndfjk.";
System.out.println(s);
Matcher m=Pattern.compile(".*",Pattern.DOTALL).matcher(s);
if (m.find()){
    s=m.group(0);
}
//将两个空格替换成一个空格
s=s.replaceAll(" {2,}"," ");
//删除每行开头所有空格,
s=s.replaceAll(" (?m)^ +","");
//将第一个匹配到的替换为(VV)
s=s.replaceFirst("[aeiou]","(VV)");
StringBuffer sb=new StringBuffer();
Pattern p=Pattern.compile("[aeiou]");//正则匹配
Matcher mm=p.matcher(s);
while (mm.find()){
    mm.appendReplacement(sb,mm.group().toUpperCase());
}
mm.appendTail(sb);//添加到StringBuffer里
System.out.println("================================");
System.out.println("sb:"+sb);aaasf. hsfhuf ijdigju,ihuih chbcjx ch
    dew.yhgy ehdywhf uila ej,lk dfn,jk
     leh ruiae, hui, lfhl kndfjk.
================================
sb: (VV)AAsf. hsfhUf IjdIgjU,IhUIh chbcjx ch
 dEw.yhgy Ehdywhf UIlA Ej,lk dfn,jk
 lEh rUIAE, hUI, lfhl kndfjk.
将现有的Matcher应用到新的字符串上,没有参数的reset()是将Matcher对象重新设置到当前字符串初始位置。
String s1="fix the rug with bags";
String s2="fix the rig with rags";
Matcher m=Pattern.compile("[frb][aiu][gx]").matcher(s1);
while (m.find())
    System.out.print(m.group()+" ");
System.out.println();
m.reset(s2);
while (m.find())
    System.out.print(m.group()+" ");fix rug bag
fix rig rag
正则与IO,在文件中进行搜索匹配操作。使用net.mindview.util.TextFile对象读取文件。
7扫描输入:
一般目前做法都是读取一行例如BufferReader的readline()
javaSE5新增Scanner类,他可以减轻扫描输入的负担。
Scanner stdin=new Scanner(BufferReader),
Scanner里有许多nextLine方法(下一行)nextInt(下一个int)nextDouble(下一个Double类型)等。Scanner可以接受任何类型的输入对象(例如:File、InputStream、String、Readable对象)
Readable对象是一个新的接口,表示具有read()方法的对象。
有了Scanner所有分词、输入、翻译的操作都隐藏在不同类型的next方法中。
7.1定界符
Scanner.useDelimiter()来设置定界符(例如用逗号来作为定界符:Scanner.useDelimiter(“\\s*,\\s”)),还有一个delimiter()方法,来返回当前正在使用的定界符。
7.2正则扫描
常用来扫描复杂数据时,用法如下
final String s="215.2.43.111@02/10/2015\n"+
        "125.3.53.134@02/10/2015\n"+
        "244.2.41.121@02/10/2015\n"+
        "232.4.42.122@02/10/2015\n"+
        "344.6.23.101@02/10/2015\n"+
        "[Next log section with different data format]";
Scanner scanner=new Scanner(s);
String pattern="(\\d+.\\d+.\\d+.\\d+)@(\\d+/\\d+/\\d+)";
while (scanner.hasNext(pattern)){
    scanner.next(pattern);
    MatchResult match=scanner.match();
    String ip=match.group(1);
    String date=match.group(2);
    System.out.printf("Threat on %s from %s \n",ip,date);
}Threat on 25.2.43.111 from 02/10/2015
Threat on 125.3.53.134 from 02/10/2015
Threat on 244.2.41.121 from 02/10/2015
Threat on 232.4.42.122 from 02/10/2015
Threat on 344.6.23.101 from 02/10/2015
(注意正则中不可以有定界符,否则不可能匹配成功)
final String s="215.2.43.111@02/10/2015\n"+
        "125.3.53.134@02,10/2015\n"+
        "244.2.41.121@02,10/2015\n"+
        "232.4.42.122@02,10/2015\n"+
        "344.6.23.101@02,10/2015\n"+
        "[Next log section with different data format]";
Scanner scanner=new Scanner(s);
scanner.useDelimiter(",");
System.out.println("delimiter:"+scanner.delimiter());
String pattern="(\\d+.\\d+.\\d+.\\d+)@(\\d+,\\d+/\\d+)";
while (scanner.hasNext(pattern)){
    scanner.next(pattern);
    MatchResult match=scanner.match();
    String ip=match.group(1);
    String date=match.group(2);
    System.out.printf("Threat on %s from %s \n",ip,date);
},

1 0
原创粉丝点击