“String类提供的正则表达式应用”的版本间的差异
		
		
		
		
		
		跳到导航
		跳到搜索
		
				
		
		
	
| Jihongchang(讨论 | 贡献)  (建立内容为“https://www.bilibili.com/video/BV1Eq4y1E79W?p=23”的新页面) | Jihongchang(讨论 | 贡献)   (→需求示例:) | ||
| (未显示同一用户的13个中间版本) | |||
| 第1行: | 第1行: | ||
| https://www.bilibili.com/video/BV1Eq4y1E79W?p=23 | https://www.bilibili.com/video/BV1Eq4y1E79W?p=23 | ||
| + | |||
| + | === 匹配替换 replaceAll === | ||
| + | |||
| + | ==== String.java 源代码 ==== | ||
| + | <syntaxhighlight lang="java"> | ||
| + | package java.lang; | ||
| + | …… | ||
| + | public final class String | ||
| + |     implements java.io.Serializable, Comparable<String>, CharSequence { | ||
| + | |||
| + | …… | ||
| + |     public String replaceAll(String regex, String replacement) { | ||
| + |         return Pattern.compile(regex).matcher(this).replaceAll(replacement); | ||
| + |     } | ||
| + | |||
| + | …… | ||
| + | |||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | ==== 需求示例: ==== | ||
| + | <syntaxhighlight lang="console"> | ||
| + | 2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布,J2SE1.3是对J2SE1.2的补充和扩展,从应用领域的角度分析,JavaSE1.3已经涵盖了数据库、WEB、网络、图形、多媒体、电话、影像等大部分的信息技术领域。 | ||
| + | |||
| + | 2002年2月26日,J2SE1.4发布。与J2SE1.3相比,多了近62%的类和接口。在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持(通过SSL与TLS协议)、全新的I/OAPI、正则表达式、日志与断言。 | ||
| + | </syntaxhighlight>将上面文字 JDK1.3 JDK1.4 统一替换成 JDK | ||
| + | |||
| + | ===== 实现1: ===== | ||
| + | <syntaxhighlight lang="java"> | ||
| + | public class StringReg { | ||
| + | |||
| + |     public static void main(String[] args) { | ||
| + | |||
| + |         String content = "2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布,J2SE1.3是对J2SE1.2的补充和扩展,从应用领域的角度分析,JavaSE1" + | ||
| + |                 ".3已经涵盖了数据库、WEB、网络、图形、多媒体、电话、影像等大部分的信息技术领域。\n" + | ||
| + |                 "\n" + | ||
| + |                 "2002年2月26日,J2SE1.4发布。与J2SE1.3相比,多了近62%的类和接口。在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持(通过SSL与TLS协议)、全新的I" + | ||
| + |                 "/OAPI、正则表达式、日志与断言。"; | ||
| + | |||
| + |         String regex = "(JDK)1\\.[3|4]"; | ||
| + | |||
| + |         String ret = content.replaceAll(regex, "$1"); | ||
| + | |||
| + |         System.out.println(ret); | ||
| + | |||
| + |     } | ||
| + | |||
| + | } | ||
| + | </syntaxhighlight><syntaxhighlight lang="console"> | ||
| + | 2000年5月,JDK、JDK和J2SE1.3相继发布,J2SE1.3是对J2SE1.2的补充和扩展,从应用领域的角度分析,JavaSE1.3已经涵盖了数据库、WEB、网络、图形、多媒体、电话、影像等大部分的信息技术领域。 | ||
| + | |||
| + | 2002年2月26日,J2SE1.4发布。与J2SE1.3相比,多了近62%的类和接口。在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持(通过SSL与TLS协议)、全新的I/OAPI、正则表达式、日志与断言。 | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ===== 实现2 ===== | ||
| + | <syntaxhighlight lang="java"> | ||
| + | public class StringReg { | ||
| + | |||
| + |     public static void main(String[] args) { | ||
| + | |||
| + |         String content = "2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布,J2SE1.3是对J2SE1.2的补充和扩展,从应用领域的角度分析,JavaSE1" + | ||
| + |                 ".3已经涵盖了数据库、WEB、网络、图形、多媒体、电话、影像等大部分的信息技术领域。\n" + | ||
| + |                 "\n" + | ||
| + |                 "2002年2月26日,J2SE1.4发布。与J2SE1.3相比,多了近62%的类和接口。在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持(通过SSL与TLS协议)、全新的I" + | ||
| + |                 "/OAPI、正则表达式、日志与断言。"; | ||
| + | |||
| + |         String regex = "JDK1\\.3|JDK1\\.4"; | ||
| + | |||
| + |         String ret = content.replaceAll(regex, "JDK"); | ||
| + | |||
| + |         System.out.println(ret); | ||
| + | |||
| + |     } | ||
| + | |||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | === 判断是否匹配 matches === | ||
| + | |||
| + | ==== String.java ==== | ||
| + | <syntaxhighlight lang="java"> | ||
| + | package java.lang; | ||
| + | …… | ||
| + | public final class String | ||
| + |     implements java.io.Serializable, Comparable<String>, CharSequence { | ||
| + | |||
| + | …… | ||
| + |     public boolean matches(String regex) { | ||
| + |         return Pattern.matches(regex, this); | ||
| + |     } | ||
| + | |||
| + | …… | ||
| + | |||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | ==== 需求示例 ==== | ||
| + | 要求验证一个手机号必须是 138 或139 开头的11位数字<syntaxhighlight lang="java"> | ||
| + | public class StringReg1 { | ||
| + | |||
| + |     public static void main(String[] args) { | ||
| + | |||
| + |         String content = "13811663445"; | ||
| + | |||
| + |         String content2 = "1381166344"; //138开头、不足11位的 | ||
| + | |||
| + |         String content3 = "13711663445"; //非138开头、11位 | ||
| + | |||
| + |         String content4 = "1381166344"; //非138开头、不足11位 | ||
| + | |||
| + |         String regex = "^13[8|9]\\d{8}"; | ||
| + | |||
| + |         System.out.println("content.matches(regex):" + content.matches(regex)); | ||
| + | |||
| + |         System.out.println("content2.matches(regex):" + content2.matches(regex)); | ||
| + | |||
| + |         System.out.println("content3.matches(regex):" + content3.matches(regex)); | ||
| + | |||
| + |         System.out.println("content4.matches(regex):" + content4.matches(regex)); | ||
| + | |||
| + |     } | ||
| + | |||
| + | } | ||
| + | </syntaxhighlight><syntaxhighlight lang="console"> | ||
| + | content.matches(regex):true | ||
| + | content2.matches(regex):false | ||
| + | content3.matches(regex):false | ||
| + | content4.matches(regex):false | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | |||
| + | === 分割 split === | ||
| + | |||
| + | ==== String.java ==== | ||
| + | <syntaxhighlight lang="java"> | ||
| + | package java.lang; | ||
| + | …… | ||
| + | public final class String | ||
| + |     implements java.io.Serializable, Comparable<String>, CharSequence { | ||
| + | |||
| + | …… | ||
| + |     public String[] split(String regex) { | ||
| + |         return split(regex, 0); | ||
| + |     } | ||
| + | |||
| + | …… | ||
| + |     public String[] split(String regex, int limit) { | ||
| + |         /* fastpath if the regex is a | ||
| + |          (1)one-char String and this character is not one of the | ||
| + |             RegEx's meta characters ".$|()[{^?*+\\", or | ||
| + |          (2)two-char String and the first char is the backslash and | ||
| + |             the second is not the ascii digit or ascii letter. | ||
| + |          */ | ||
| + |         char ch = 0; | ||
| + |         if (((regex.value.length == 1 && | ||
| + |              ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) || | ||
| + |              (regex.length() == 2 && | ||
| + |               regex.charAt(0) == '\\' && | ||
| + |               (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 && | ||
| + |               ((ch-'a')|('z'-ch)) < 0 && | ||
| + |               ((ch-'A')|('Z'-ch)) < 0)) && | ||
| + |             (ch < Character.MIN_HIGH_SURROGATE || | ||
| + |              ch > Character.MAX_LOW_SURROGATE)) | ||
| + |         { | ||
| + |             int off = 0; | ||
| + |             int next = 0; | ||
| + |             boolean limited = limit > 0; | ||
| + |             ArrayList<String> list = new ArrayList<>(); | ||
| + |             while ((next = indexOf(ch, off)) != -1) { | ||
| + |                 if (!limited || list.size() < limit - 1) { | ||
| + |                     list.add(substring(off, next)); | ||
| + |                     off = next + 1; | ||
| + |                 } else {    // last one | ||
| + |                     //assert (list.size() == limit - 1); | ||
| + |                     list.add(substring(off, value.length)); | ||
| + |                     off = value.length; | ||
| + |                     break; | ||
| + |                 } | ||
| + |             } | ||
| + |             // If no match was found, return this | ||
| + |             if (off == 0) | ||
| + |                 return new String[]{this}; | ||
| + | |||
| + |             // Add remaining segment | ||
| + |             if (!limited || list.size() < limit) | ||
| + |                 list.add(substring(off, value.length)); | ||
| + | |||
| + |             // Construct result | ||
| + |             int resultSize = list.size(); | ||
| + |             if (limit == 0) { | ||
| + |                 while (resultSize > 0 && list.get(resultSize - 1).length() == 0) { | ||
| + |                     resultSize--; | ||
| + |                 } | ||
| + |             } | ||
| + |             String[] result = new String[resultSize]; | ||
| + |             return list.subList(0, resultSize).toArray(result); | ||
| + |         } | ||
| + |         return Pattern.compile(regex).split(this, limit); | ||
| + |     } | ||
| + | …… | ||
| + | |||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ==== 需求示例: ==== | ||
| + | 将 "hello#abc-jack12smith~北京" 按照 #或-或~或数字来分割<syntaxhighlight lang="java"> | ||
| + | public class StringReg2 { | ||
| + | |||
| + |     public static void main(String[] args) { | ||
| + | |||
| + |         String content = "hello#abc-jack12smith~北京"; | ||
| + | |||
| + |         String[] arr = content.split("[#|\\-|~|\\d]+"); | ||
| + | |||
| + |         for (String str : arr) { | ||
| + |             System.out.println(str); | ||
| + |         } | ||
| + | |||
| + |     } | ||
| + | |||
| + | } | ||
| + | </syntaxhighlight><syntaxhighlight lang="console"> | ||
| + | hello | ||
| + | abc | ||
| + | jack | ||
| + | smith | ||
| + | 北京 | ||
| + | </syntaxhighlight>下面这个也行:<syntaxhighlight lang="java"> | ||
| + | public class StringReg2 { | ||
| + | |||
| + |     public static void main(String[] args) { | ||
| + | |||
| + |         String content = "hello#abc-jack12smith~北京"; | ||
| + | |||
| + |         String[] arr = content.split("#|-|~|\\d+"); | ||
| + | |||
| + |         for (String str : arr) { | ||
| + |             System.out.println(str); | ||
| + |         } | ||
| + | |||
| + |     } | ||
| + | |||
| + | } | ||
| + | </syntaxhighlight> | ||
2022年11月20日 (日) 10:56的最新版本
https://www.bilibili.com/video/BV1Eq4y1E79W?p=23
匹配替换 replaceAll
String.java 源代码
package java.lang;
……
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    
……
    public String replaceAll(String regex, String replacement) {
        return Pattern.compile(regex).matcher(this).replaceAll(replacement);
    }
……
}
需求示例:
2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布,J2SE1.3是对J2SE1.2的补充和扩展,从应用领域的角度分析,JavaSE1.3已经涵盖了数据库、WEB、网络、图形、多媒体、电话、影像等大部分的信息技术领域。
2002年2月26日,J2SE1.4发布。与J2SE1.3相比,多了近62%的类和接口。在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持(通过SSL与TLS协议)、全新的I/OAPI、正则表达式、日志与断言。
将上面文字 JDK1.3 JDK1.4 统一替换成 JDK
实现1:
public class StringReg {
    public static void main(String[] args) {
        String content = "2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布,J2SE1.3是对J2SE1.2的补充和扩展,从应用领域的角度分析,JavaSE1" +
                ".3已经涵盖了数据库、WEB、网络、图形、多媒体、电话、影像等大部分的信息技术领域。\n" +
                "\n" +
                "2002年2月26日,J2SE1.4发布。与J2SE1.3相比,多了近62%的类和接口。在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持(通过SSL与TLS协议)、全新的I" +
                "/OAPI、正则表达式、日志与断言。";
        String regex = "(JDK)1\\.[3|4]";
        String ret = content.replaceAll(regex, "$1");
        System.out.println(ret);
    }
}
2000年5月,JDK、JDK和J2SE1.3相继发布,J2SE1.3是对J2SE1.2的补充和扩展,从应用领域的角度分析,JavaSE1.3已经涵盖了数据库、WEB、网络、图形、多媒体、电话、影像等大部分的信息技术领域。
2002年2月26日,J2SE1.4发布。与J2SE1.3相比,多了近62%的类和接口。在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持(通过SSL与TLS协议)、全新的I/OAPI、正则表达式、日志与断言。
实现2
public class StringReg {
    public static void main(String[] args) {
        String content = "2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布,J2SE1.3是对J2SE1.2的补充和扩展,从应用领域的角度分析,JavaSE1" +
                ".3已经涵盖了数据库、WEB、网络、图形、多媒体、电话、影像等大部分的信息技术领域。\n" +
                "\n" +
                "2002年2月26日,J2SE1.4发布。与J2SE1.3相比,多了近62%的类和接口。在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持(通过SSL与TLS协议)、全新的I" +
                "/OAPI、正则表达式、日志与断言。";
        String regex = "JDK1\\.3|JDK1\\.4";
        String ret = content.replaceAll(regex, "JDK");
        System.out.println(ret);
    }
}
判断是否匹配 matches
String.java
package java.lang;
……
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    
……
    public boolean matches(String regex) {
        return Pattern.matches(regex, this);
    }
……
}
需求示例
要求验证一个手机号必须是 138 或139 开头的11位数字
public class StringReg1 {
    public static void main(String[] args) {
        String content = "13811663445";
        String content2 = "1381166344"; //138开头、不足11位的
        String content3 = "13711663445"; //非138开头、11位
        String content4 = "1381166344"; //非138开头、不足11位
        String regex = "^13[8|9]\\d{8}";
        System.out.println("content.matches(regex):" + content.matches(regex));
        System.out.println("content2.matches(regex):" + content2.matches(regex));
        System.out.println("content3.matches(regex):" + content3.matches(regex));
        System.out.println("content4.matches(regex):" + content4.matches(regex));
    }
}
content.matches(regex):true
content2.matches(regex):false
content3.matches(regex):false
content4.matches(regex):false
分割 split
String.java
package java.lang;
……
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    
……
    public String[] split(String regex) {
        return split(regex, 0);
    }
……
    public String[] split(String regex, int limit) {
        /* fastpath if the regex is a
         (1)one-char String and this character is not one of the
            RegEx's meta characters ".$|()[{^?*+\\", or
         (2)two-char String and the first char is the backslash and
            the second is not the ascii digit or ascii letter.
         */
        char ch = 0;
        if (((regex.value.length == 1 &&
             ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
             (regex.length() == 2 &&
              regex.charAt(0) == '\\' &&
              (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
              ((ch-'a')|('z'-ch)) < 0 &&
              ((ch-'A')|('Z'-ch)) < 0)) &&
            (ch < Character.MIN_HIGH_SURROGATE ||
             ch > Character.MAX_LOW_SURROGATE))
        {
            int off = 0;
            int next = 0;
            boolean limited = limit > 0;
            ArrayList<String> list = new ArrayList<>();
            while ((next = indexOf(ch, off)) != -1) {
                if (!limited || list.size() < limit - 1) {
                    list.add(substring(off, next));
                    off = next + 1;
                } else {    // last one
                    //assert (list.size() == limit - 1);
                    list.add(substring(off, value.length));
                    off = value.length;
                    break;
                }
            }
            // If no match was found, return this
            if (off == 0)
                return new String[]{this};
            // Add remaining segment
            if (!limited || list.size() < limit)
                list.add(substring(off, value.length));
            // Construct result
            int resultSize = list.size();
            if (limit == 0) {
                while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
                    resultSize--;
                }
            }
            String[] result = new String[resultSize];
            return list.subList(0, resultSize).toArray(result);
        }
        return Pattern.compile(regex).split(this, limit);
    }
……
}
需求示例:
将 "hello#abc-jack12smith~北京" 按照 #或-或~或数字来分割
public class StringReg2 {
    public static void main(String[] args) {
        String content = "hello#abc-jack12smith~北京";
        String[] arr = content.split("[#|\\-|~|\\d]+");
        for (String str : arr) {
            System.out.println(str);
        }
    }
}
hello
abc
jack
smith
北京
下面这个也行:
public class StringReg2 {
    public static void main(String[] args) {
        String content = "hello#abc-jack12smith~北京";
        String[] arr = content.split("#|-|~|\\d+");
        for (String str : arr) {
            System.out.println(str);
        }
    }
}