java-正则表达式 2

7. 复杂的正则表达式示例(续)

7.1 验证日期格式

以下正则表达式用于验证日期格式,例如YYYY-MM-DD。

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String[] dates = {
            "2023-01-01",
            "2023-13-01", // 无效月份
            "2023-12-32", // 无效日期
            "2023-02-29", // 非闰年的无效日期
            "2024-02-29"  // 闰年的有效日期
        };

        String patternString = "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$";
        Pattern pattern = Pattern.compile(patternString);

        for (String date : dates) {
            Matcher matcher = pattern.matcher(date);
            System.out.println(date + ": " + matcher.matches());
        }
    }
}

在上述代码中,正则表达式^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$用于验证日期格式。该表达式验证了年份的格式为四位数字,月份为01到12,日期为01到31。

8. 正则表达式的高级用法

8.1 捕获组和非捕获组

捕获组通过圆括号()来定义,非捕获组通过(?:...)来定义。捕获组会保存匹配到的内容,而非捕获组不会。

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String text = "The price is $123.45";

        String patternString = "(\\$)(\\d+\\.\\d{2})";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(text);

        if (matcher.find()) {
            System.out.println("Full match: " + matcher.group(0)); // 输出:$123.45
            System.out.println("Currency symbol: " + matcher.group(1)); // 输出:$
            System.out.println("Amount: " + matcher.group(2)); // 输出:123.45
        }
    }
}

在上述代码中,正则表达式(\\$)(\\d+\\.\\d{2})用于匹配带有货币符号的金额。捕获组用于提取货币符号和金额部分。

8.2 断言

断言是一种零宽度匹配,分为正向断言和负向断言。

  • • 正向断言(?=...):匹配某个位置前面满足特定条件的字符。
  • • 负向断言(?!...):匹配某个位置前面不满足特定条件的字符。
import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String text = "foo123bar";

        // 正向断言:匹配数字前面是foo的部分
        String patternString1 = "foo(?=\\d)";
        Pattern pattern1 = Pattern.compile(patternString1);
        Matcher matcher1 = pattern1.matcher(text);
        if (matcher1.find()) {
            System.out.println("Positive Lookahead: " + matcher1.group()); // 输出:foo
        }

        // 负向断言:匹配数字前面不是foo的部分
        String patternString2 = "(?<!foo)\\d";
        Pattern pattern2 = Pattern.compile(patternString2);
        Matcher matcher2 = pattern2.matcher(text);
        while (matcher2.find()) {
            System.out.println("Negative Lookbehind: " + matcher2.group());
        }
    }
}

在上述代码中,正向断言用于匹配数字前面是foo的部分,负向断言用于匹配数字前面不是foo的部分。

8.3 贪婪、勉强和占有量词

量词用于指定匹配的数量,量词可以是贪婪的、勉强的或占有的。

  • • 贪婪量词(默认):尽可能多地匹配。比如*+?
  • • 勉强量词:尽可能少地匹配。比如*?+???
  • • 占有量词:尽可能多地匹配且不回溯。比如*+++?+
import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String text = "aaaa";

        // 贪婪量词:尽可能多地匹配
        String patternString1 = "a+";
        Pattern pattern1 = Pattern.compile(patternString1);
        Matcher matcher1 = pattern1.matcher(text);
        if (matcher1.find()) {
            System.out.println("Greedy: " + matcher1.group()); // 输出:aaaa
        }

        // 勉强量词:尽可能少地匹配
        String patternString2 = "a+?";
        Pattern pattern2 = Pattern.compile(patternString2);
        Matcher matcher2 = pattern2.matcher(text);
        if (matcher2.find()) {
            System.out.println("Reluctant: " + matcher2.group()); // 输出:a
        }

        // 占有量词:尽可能多地匹配且不回溯
        String patternString3 = "a++";
        Pattern pattern3 = Pattern.compile(patternString3);
        Matcher matcher3 = pattern3.matcher(text);
        if (matcher3.find()) {
            System.out.println("Possessive: " + matcher3.group()); // 输出:aaaa
        }
    }
}

在上述代码中,分别演示了贪婪量词、勉强量词和占有量词的匹配行为。

9. 正则表达式的性能优化

正则表达式的性能可能会受到匹配模式和输入数据的影响。在编写正则表达式时,应该考虑以下优化策略:

9.1 避免回溯

使用贪婪量词可能导致回溯,从而影响性能。尽量使用勉强量词或占有量词来减少回溯。

9.2 使用预编译的Pattern

避免在每次匹配时都重新编译正则表达式。可以将正则表达式预编译成Pattern对象并重用。

public class RegexExample {
    private static final Pattern pattern = Pattern.compile("\\d+");

    public static void main(String[] args) {
        String text = "123 456 789";
        Matcher matcher = pattern.matcher(text);
        while (matcher.find()) {
            System.out.println("Found: " + matcher.group());
        }
    }
}
9.3 优化正则表达式

简化和优化正则表达式,使其更高效。例如,使用字符类而不是单独的字符匹配。

String patternString1 = "[aeiou]"; // 使用字符类
String patternString2 = "a|e|i|o|u"; // 使用单独字符匹配

10. 常见正则表达式示例

10.1 验证IP地址

以下正则表达式用于验证IPv4地址的格式。

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String[] ips = {
            "192.168.0.1",
            "255.255.255.255",
            "256.256.256.256", // 无效IP地址
            "192.168.1.300"   // 无效IP地址
        };

        String patternString = "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$";
        Pattern pattern = Pattern.compile(patternString);

        for (String ip : ips) {
            Matcher matcher = pattern.matcher(ip);
            System.out.println(ip + ": " + matcher.matches());
        }
    }
}

在上述代码中,正则表达式^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$用于验证IPv4地址的格式。

11. 工具和框架中的正则表达式

正则表达式在各种工具和框架中得到了广泛应用。例如:

  • • 文本编辑器和IDE:许多文本编辑器和IDE支持正则表达式搜索和替换。
  • • Web框架:Web框架使用正则表达式进行URL路由和参数验证。
  • • 数据处理工具:正则表达式用于数据清洗和解析。
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值