【正则表达式(在Java中的运用)】

正则表达式详解

1. 基本字符匹配
  • 普通字符:大多数字符在正则表达式中表示它们自身,例如a匹配字符a
  • 特殊字符:如.*+等,它们在正则表达式中有特殊含义。
2. 元字符
  • .:匹配除换行符外的任意字符。
  • \d:匹配任意数字,等同于[0-9]
  • \D:匹配任意非数字字符。
  • \w:匹配字母、数字或下划线,等同于[a-zA-Z0-9_]
  • \W:匹配非字母、数字或下划线的字符。
  • \s:匹配任意空白字符,包括空格、制表符、换行符等。
  • \S:匹配任意非空白字符。
3. 字符类
  • [abc]:匹配abc中的任意一个字符。
  • [^abc]:匹配除了abc之外的任意字符。
  • [a-z]:匹配任意小写字母。
  • [A-Z]:匹配任意大写字母。
  • [0-9]:匹配任意数字。
4. 量词
  • *:匹配前面的字符0次或多次。
  • +:匹配前面的字符1次或多次。
  • ?:匹配前面的字符0次或1次。
  • {n}:匹配前面的字符恰好n次。
  • {n,}:匹配前面的字符至少n次。
  • {n,m}:匹配前面的字符至少n次,至多m次。
5. 边界匹配
  • ^:匹配行的开始。
  • $:匹配行的结束。
  • \b:匹配单词边界。
  • \B:匹配非单词边界。
6. 分组和捕获
  • (abc):将abc作为一个整体进行匹配,并创建一个捕获组。
  • (?:abc):非捕获组,只匹配不捕获。
7. 反向引用
  • \1:引用第一个捕获组的内容。
  • \2:引用第二个捕获组的内容。
示例:
  • 匹配邮箱地址\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b
  • 匹配电话号码\d{3}-\d{4}-\d{4}
  • 匹配URLhttps?://[^\s]+
  • 匹配HTML标签<([a-zA-Z]+)[^>]*>.*?</\1>
正则表达式的应用:
  1. 文本搜索:在文本编辑器中查找特定的字符串。
  2. 文本替换:替换文本中的某些部分,如批量修改文件名。
  3. 数据验证:验证用户输入的数据格式是否正确,如邮箱、电话号码等。
  4. 数据提取:从文本中提取特定的信息,如从日志文件中提取错误信息。
建议:
  • 实践是学习正则表达式的最佳方式。尝试在不同的场景下使用正则表达式,如在文本编辑器、编程语言中进行搜索和替换。
  • 使用在线正则表达式测试工具,如regex101.com,可以帮助你理解和测试正则表达式。
  • 阅读正则表达式的文档和教程,理解不同元字符和量词的含义和用法。
  • 尝试解决实际问题,如编写一个正则表达式来验证用户输入的密码是否符合要求。
示例:

在桌面角色扮演游戏(TRPG,俗称“跑团”)中,玩家需要掷出若干个骰子,根据掷出的结果推进游戏进度。在线上同样可以跑团,方法是由玩家们向机器人发出指令,由机器人随机产生每个需要掷出的骰子的结果。

玩家向机器人发出的指令是一个仅涉及加法和减法的表达式,即对若干个数字进行一系列加法或减法计算。这些数字可以是直接给出的非负整数(数字不超过 1000),也可以是若干个骰子掷出的结果。

“掷骰子”这个动作对应的指令格式为 xdy,表示摇动 x 个 y 面的骰子(1≤x≤1000,2≤y≤1000)。当 x 为 1 时,1 可以省略。

例如指令 2d3+3-d4 的意思是:先掷出 2 个 3 面骰子(你不必考虑现实中是否存在这样的骰子),不妨假设结果为 1 和 3,则 2d3 的结果就是两个骰子的面值之和 4;然后计算 4 + 3,得到结果为 7;再掷出 1 个 4 面骰子,不妨假设结果为 2,则计算 7 - 2 得到最终结果 5。

本题就请你计算玩家输入的指令里,不同种类的骰子需要掷出几个,以及可能得到的结果在什么区间范围内。

输入格式:
输入在一行中给出一条符合题目描述的玩家输入机器人的指令。题目保证指令长度不超过 20000

输出格式:
首先输出不同种类的骰子分别需要掷出几个。每种骰子的信息占一行,依次输出骰子的面数和投掷的数量,按面数从小到大输出。
输入指令保证至少有一个骰子需要掷出。
最后一行输出两个数,表示根据输入指令可以得到的最小结果和最大结果。
同一行数字间以 1 个空格分隔,行首尾不得有多余空格。

题解:

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
	public static void main(String[] args) {
		String input = "d6+3d5+2-2d3+2d5"; // 示例输入,实际应用中应从控制台读取
		Map<Integer, Integer> diceMap = new HashMap<>();
		int minSum = 0;
		int maxSum = 0;

		// 正则表达式匹配所有骰子指令和数字
		Pattern pattern = Pattern.compile("(\\d*)d(\\d+)|(\\+|-)(\\d+)");
		Matcher matcher = pattern.matcher(input);

		while (matcher.find()) {
			if (matcher.group(2) != null) {
				// 匹配到骰子指令,例如 "2d6"
				int count = matcher.group(1).isEmpty() ? 1 : Integer.parseInt(matcher.group(1));
				int sides = Integer.parseInt(matcher.group(2));
				diceMap.put(sides, diceMap.getOrDefault(sides, 0) + count);
				// 更新最小值和最大值
				minSum += (count > 1) ? (sides * (count - 1)) : 0; // 减去多余的最小值
				maxSum += (count > 1) ? (sides * count) : sides;
			} else if (matcher.group(3) != null) {
				// 匹配到数字,例如 "+3"
				int number = Integer.parseInt(matcher.group(4));
				minSum += (matcher.group(3).equals("+")) ? number : -number;
				maxSum += number; // 最大值只考虑正数
			}
		}

		// 输出每种骰子的数量
		for (Map.Entry<Integer, Integer> entry : diceMap.entrySet()) {
			System.out.println(entry.getKey() + " " + entry.getValue());
		}
		// 输出最小结果和最大结果
		System.out.println(minSum + " " + maxSum);
	}
}

注:
在Java中,正则表达式中的特殊字符需要进行转义,以便正确地表示它们。在正则表达式中,\d表示匹配任意数字(0-9)。然而,在Java字符串中,反斜杠\本身就是一个转义字符,因此如果你想在字符串中表示一个反斜杠,你需要使用两个反斜杠\\

当你在Java代码中写"\\d+"时,第一个反斜杠\是用来转义第二个反斜杠\的,这样Java就会将\\解释为一个单独的反斜杠字符。然后,这个单独的反斜杠\再去转义后面的d,告诉Java这是一个正则表达式中的特殊字符\d,而不是普通的字符d

所以,当你在Java代码中看到"\\d+"时,它实际上是表示正则表达式中的\d+,其中\d匹配任意数字,而+表示前面的元素(在这里是\d)应该出现一次或多次。

总结一下,Java字符串中的"\\d+"实际上对应于正则表达式中的\d+,但由于Java字符串中反斜杠的转义规则,你需要在字符串中写成"\\d+"

  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值