zoukankan      html  css  js  c++  java
  • Java字符串的那些事儿。。。。

    计划围绕以下几个方面 

    1.内存

    2.正则表达式  

    3.String.format

    4.编码

    1.内存

      先来看个经典的例子

    public class Blog {
        public static void main(String[] args) {
            String s0 = "123";
            String s1 = "123";
            String s2 = new String("123");
            String s3 = new String("123");
    
            System.out.println(s0 == s1);// true
            System.out.println(s2 == s3);// false
            System.out.println(s1 == s2);// false
        }
    }

      String是字符串常量,java.lang.String被设计为final类,不允许被继承和修改。 例子中的s0和s1都相当于常量,直接放在内存的stack中。而s2和s3作为引用类型被new出来,都是放在heap中。而java的 == 是直接判断栈中的值,所以s0和s1相等,而当用s1和s2比较时,实际是用s1在stack中的“123”和s2在stack中引用的内存地址相比较,所以不相等。

      String不是基本数据类型,如果需要使用字符串变量时应该使用StringBuffer或者StringBuilder,前者线程安全。

    ————————————————————————————————————————————————————————

    2.正则

    首先介绍几个java.lang.String中的常用使用正则的方法:

    String.matches

    String.replaceAll

    String.replaceFirst

    String.split

    下面是例子代码

    public class Blog {
        public static void main(String[] args) {
            String s0 = "ccc123aaa456bbb";
            System.out.println(s0.matches(".*\d+.*"));
            System.out.println(new String(s0).replaceAll("\d", "-"));
            System.out.println(new String(s0).replaceFirst("\d", "-"));
            
            String[] split = s0.split("\d+");
            for (String string : split) {
                System.out.println(string);
            }
        }
    }

    matches用来判断一个字符串是否符合某些规则,比如常见的邮箱合法检测都可以用正则来实现。

    split是分割,把字符串按其中匹配正则的子串切割成几段返回字符串数组。

    replaceAll和replaceFirst是将string中的符合此正则的串替换成想要替换的字符串。

    这个在开发中也可以用,如果使用Eclipse想把一个很长的串比如“aaa”,“aaa”,“aaa”,“aaa”,“aaa”,“aaa”,想分成多行排列,可以使用ctrl+F中的Regular expression

    然后replaceAll即可。

    而java提供的正则工具类是

    java.util.regex.Pattern和java.util.regex.Matcher
     
    例子
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class Blog {
        public static void main(String[] args) {
            Pattern pattern = Pattern.compile("\d");
            Matcher matcher = pattern.matcher("1");
            boolean result = matcher.find();
            System.out.println(result);
        }
    }

    关于正则的规则,可以在java doc的java.util.regex.Pattern中找到详细介绍。要注意java的正则和其他js等语言的正则不一定完全通用,因为各个语言正则使用的标准不一定一样。

    简单贴几条

    字符
    x 字符 x
    \ 反斜线字符
    n 带有八进制值 0 的字符 n (0 <= n <= 7)
    nn 带有八进制值 0 的字符 nn (0 <= n <= 7)
    mnn 带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7)
    xhh 带有十六进制值 0x 的字符 hh
    uhhhh 带有十六进制值 0x 的字符 hhhh
    制表符 ('u0009')
    新行(换行)符 ('u000A')
    回车符 ('u000D')
    f 换页符 ('u000C')
    a 报警 (bell) 符 ('u0007')
    e 转义符 ('u001B')
    cx 对应于 x 的控制符
     
    字符类
    [abc] abc(简单类)
    [^abc] 任何字符,除了 abc(否定)
    [a-zA-Z] azAZ,两头的字母包括在内(范围)
    [a-d[m-p]] admp[a-dm-p](并集)
    [a-z&&[def]] def(交集)
    [a-z&&[^bc]] az,除了 bc[ad-z](减去)
    [a-z&&[^m-p]] az,而非 mp[a-lq-z](减去)
     
    预定义字符类
    . 任何字符(与行结束符可能匹配也可能不匹配)
    d 数字:[0-9]
    D 非数字: [^0-9]
    s 空白字符:[ x0Bf ]
    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} 空格或制表符:[ ]
    p{Cntrl} 控制字符:[x00-x1Fx7F]
    p{XDigit} 十六进制数字:[0-9a-fA-F]
    p{Space} 空白字符:[ x0Bf ]
     
    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 非单词边界
    A 输入的开头
    G 上一个匹配的结尾
     输入的结尾,仅用于最后的结束符(如果有的话)
    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 XY
    (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,作为独立的非捕获组

    要注意有些正则需要转义。而如果正则要转义java又要转义,那很可能会出现\\的情况比如

    public class Blog {
        public static void main(String[] args) {
            System.out.println("\".matches("\\"));    // true
            System.out.println("\".matches("\"));      // err
        }
    }

    3.string.format()

    String.format相关资料可以参考这里http://developer.51cto.com/art/201203/322815.htm

    就不赘述了。比较常用的功能就是把数据整理成各种格式,比如2013.12.12转成2013-12-12,或者把一个0到100的数字整理成001,014,068这种,很方便。

    4.编码。

      比如一个String "不要啊"。

      内存中是不会存放中文的,计算机只认识0和1。

      可以看一下下面的例子。

      

    import java.io.UnsupportedEncodingException;
    
    public class TestChar {
        public static void main(String[] args) {
            String s = new String("不要啊");
            byte[] bytes;
            try {
                bytes = s.getBytes("GBK");
                for (byte b : bytes) {
                    System.out.print(b + " ");
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    }

    打印结果是6个byte。

    而当把GBK换成utf-8的时候,打印结果就是9个byte。因为utf-8中一个中文占3个字节。

    转换编码可以这样

    public class TestChar {
        public static void main(String[] args) {
            String s0 = new String("不要啊");
            String s1;
            try {
                s1 = new String(s0.getBytes(), "GBK");
                System.out.println(s1);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    }

    当然这样转换会有乱码的可能。

    转码也可以用java.net.URLEncoder.encode(String s, String enc)

    好了就写这些吧,不对不足之处还望指出。

  • 相关阅读:
    Reactive Extensions (Rx) 入门(5) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(4) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(3) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(2) —— 安装 Reactive Extensions
    Reactive Extensions (Rx) 入门(1) —— Reactive Extensions 概要
    Xamarin NuGet 缓存包导致 already added : Landroid/support/annotation/AnimRes 问题解决方案
    Android 系统Action大全
    Xamarin Forms 实现发送通知点击跳转
    如何理解灰度发布
    推荐一款分布式微服务框架 Surging
  • 原文地址:https://www.cnblogs.com/xirtam/p/3479887.html
Copyright © 2011-2022 走看看