zoukankan      html  css  js  c++  java
  • Java 正则表达式

    正则表达式

    概述

    正则表达式定义了字符串的模式。正则表达式可以用来搜索、编辑或处理文本。正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。

    java.util.regex 包主要包括以下三个类:

    • Pattern 类:

      pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。

    • Matcher 类:

      Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

    • PatternSyntaxException:

      PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

    语法

    根据 Java Language Specification 的要求,Java 源代码的字符串中的反斜线被解释为 Unicode 转义或其他字符转义。因此必须在字符串字面值中使用两个反斜线,表示正则表达式受到保护,不被 Java 字节码编译器解释。例如,当解释为正则表达式时,字符串字面值 "" 与单个退格字符匹配,而 " " 与单词边界匹配。字符串字面值 "(hello)" 是非法的,将导致编译时错误;要与字符串 (hello) 匹配,必须使用字符串字面值 "\(hello\)"

    常见匹配符号

    1. 任意一个字符串表示匹配任意对应的字符,如a匹配a,7匹配7,-匹配-
    2. ^regex正则必须匹配字符串开头
    3. regex$正则必须匹配字符串结尾
    4. []代表匹配中括号中的任一个字符如[abc]匹配a或b或c
    5. -在中括号中不匹配自己,比如[a-z]代表匹配匹配26个小写字母中的任一个;[a-zA-Z]匹配大小写共52个字母中任一个;[0-9]匹配十个数字中任一个。
    6. 在中括号中与外面不同。在外时,就表示开头,如7[0-9]表示匹配开头是7的,且第二位是任一数字的字符串。如果在中括号里面,表示除了这个字符之外的任意字符(包括数字,特殊字符),如[^abc]表示匹配出去abc之外的其他任一字符。
    7. 点.表示匹配任意的字符
    8. XY表示X后面跟着Y,这里X和Y分别是正则表达式的一部分。
    9. 匹配 xy。例如,'z|food' 匹配"z"或"food"。'(z|f)ood' 匹配"zood"或"food"。

    示例:

    • [jpg|png] 代表匹配 jpgpng 中的任意一个字符。
    • (jpg|png) 代表匹配 jpgpng

    元字符(是一个预定义的字符)

    1. d表示数字
    2. D表示非数字
    3. s表示匹配任何空白字符,包括空格、制表符、换页符等。与 [ f v] 等效。
    4. S匹配任何非空白字符。与 [ ^f v] 等效。
    5. w表示字母数字下划线匹配任何字类字符,包括下划线。与"[A-Za-z0-9_]"等效。
    6. W与任何非单词字符匹配。与[ ^A-Za-z0-9_]等效。

    限定符(定义了一个元素可以发生的概率)

    1. ?表示出现0次或1次。例如,"do(es)?"匹配"do"或"does"中的"do"。? 等效于 {0,1}。
    2. +表示出现1次或多次。例如,"zo+"与"zo"和"zoo"匹配,但与"z"不匹配。+ 等效于 {1,}。
    3. *表示出现0次、1次或多次。 如,zo *匹配“z”和“zoo”。等效于{0,}
    4. {n}表示出现n次。
    5. {n,m}表示出现n~m次。
    6. {n,}表示出现n次或n次以上。

    分组和反向引用

    小括号 () 可以达到对正则表达式进行分组的效果。

    在以正则表达式替换字符串的语法中,是通过 $ 来引用分组的反向引用,$0 是匹配完整模式的字符串(注意在 JavaScript 中是用 $& 表示);$1 是第一个分组的反向引用;$2 是第二个分组的反向引用,以此类推。

    例如:

    package com.wuxianjiezh.demo.regex;
    public class RegexTest {
    
        public static void main(String[] args) {
            // 去除单词与 , 和 . 之间的空格
            String Str = "Hello , World .";
            String pattern = "(\w)(\s+)([.,])";
            // $0 匹配 `(w)(s+)([.,])` 结果为 `o空格,` 和 `d空格.`
            // $1 匹配 `(w)` 结果为 `o` 和 `d`
            // $2 匹配 `(s+)` 结果为 `空格` 和 `空格`
            // $3 匹配 `([.,])` 结果为 `,` 和 `.`
            System.out.println(Str.replaceAll(pattern, "$1$3")); // Hello, World.
        }
    }
    

    当我们在小括号 () 内的模式开头加入 ?:,那么表示这个模式仅分组,但不创建反向引用。

    否定先行断言

    我们可以创建否定先行断言模式的匹配,即某个字符串后面不包含另一个字符串的匹配模式。

    否定先行断言模式通过 (?!pattern) 定义。比如,我们匹配后面不是跟着 "b" 的 "a":a(?!b)

    Java中的反斜杠

    反斜杠 在 Java 中表示转义字符,这意味着 在 Java 拥有预定义的含义。

    这里例举两个特别重要的用法:

    • 在匹配 .{[(?$^* 这些特殊字符时,需要在前面加上 \,比如匹配 . 时,Java 中要写为 \.,但对于正则表达式来说就是 .
    • 在匹配 时,Java 中要写为 \\,但对于正则表达式来说就是 \

    注意:Java 中的正则表达式字符串有两层含义,首先 Java 字符串转义出符合正则表达式语法的字符串,然后再由转义后的正则表达式进行模式匹配。

    在字符串中使用正则表达式

    在 Java 中有四个内置的运行正则表达式的方法,分别是 matches()split())replaceFirst()replaceAll()。注意 replace() 方法不支持正则表达式。

    方法 描述
    s.matchs("regex") 当且仅当正则匹配整个字符串时返回true
    s.split("regex") 按匹配的正则表达式切片字符串
    s,replaceFirst("regex","replacement") 替换首次匹配的字符串片段
    s.replaceAll("regex","replacement") 替换所有匹配的字符

    模式和匹配

    Java 中使用正则表达式需要用到两个类,分别为 java.util.regex.Patternjava.util.regex.Matcher

    package com.wuxianjiezh.regex;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    public class RegexTest {
    
        public static void main(String[] args) {
            String text = "Hello Regex!";
    		//第一步通过正则表达式创建模式对象Pattern
            Pattern pattern = Pattern.compile("\w+");
            // Java 中忽略大小写,有两种写法:
            // Pattern pattern = Pattern.compile("\w+", Pattern.CASE_INSENSITIVE);
            // Pattern pattern = Pattern.compile("(?i)\w+"); // 推荐写法
            //第二步,通过模式对象根据自定字符串创建匹配对象
            Matcher matcher = pattern.matcher(text);
            //第三步,根据匹配对象Matcher根据正则表达式创建对象
            // 遍例所有匹配的序列
            while (matcher.find()) {
                System.out.print("Start index: " + matcher.start());
                System.out.print(" End index: " + matcher.end() + " ");
                System.out.println(matcher.group());
            }
            // 创建第两个模式,将空格替换为 tab
            Pattern replace = Pattern.compile("\s+");
            Matcher matcher2 = replace.matcher(text);
            System.out.println(matcher2.replaceAll("	"));
        }
    }
    

    常见示例

    匹配中文

    [u4e00-u9fa5]+ 代表匹配中文字。

    数字范围

    正则表达式匹配数字范围时,首先要确定最大值与最小值,最后写中间值。比如,匹配 1990 到 2017。

    注意:这里有个新手易范的错误,就是正则 [1990-2017],实际这个正则只匹配 01279 中的任一个字符。

    "^1990$|^199[1-9]$|^20[0-1][0-6]$|^2017$" 为判断 1990-2017 正确的正则表达式
    

    img标签的匹配

    // 这里考虑了一些不规范的 img 标签写法,比如:空格、引号
    Pattern pattern = Pattern.compile("<img\s+src=(?:['"])?(?<src>\w+.(jpg|png))(?:['"])?\s*/>");
    

    参考资料:segmentfault,菜鸟

    作者:Loserfromlazy
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    JQuery-文档处理&选择器
    JQuery-事件(部分)
    JS中构造函数与函数
    JS中的String.Math.Date
    JS中的_proto_(2)
    JS中的_proto_
    JS中的constructor
    mysql 安装问题
    【转】SpringMVC中DispatcherServlet配置中url-pattern 配置/*和/的区别
    【转】MySql中的函数
  • 原文地址:https://www.cnblogs.com/yhr520/p/12576481.html
Copyright © 2011-2022 走看看