Java正则表达式实例

本文详细介绍了如何使用Java正则表达式处理文件合并与文本替换任务,通过读取两个文件并根据映射关系替换特定占位符,实现文本内容的动态生成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[size=medium]题目[/size]:

有两个文件context.txt和words.conf,请尝试将他们合并成为一段文字,并打印出来。

[size=medium]文件内容[/size]:

[b]context.txt[/b]

[color=blue]“并不是每个人都需要$(qunar)自己的粮食,$(flight.1)每个人都需要做自己穿的$(flight.2),我们说着别人发明的$(hotel),使用别人发明的数学......我们一直在$(tuan)别人的成果。使用人类的已有经验和知识$(travel.1)来进行,是一件$(travel.2)的事情”
[/color]

[b]words.conf[/b]
[color=green]
flight=也不是:衣服

qunar=种植

hotel=语言

tuan=使用

travel=发明创造:很了不起
[/color]

[size=medium]分析[/size]

context.txt包含占位符(键)的文本,words.conf为键和值的映射,需要将占位符(键)替换为实际值。

[b]context.txt[/b]

占位符都是以$开头,一对圆括号包围,$和()在正则表达式里有特殊含义,需要用反斜杠转义;里面的键虽然不同,但都是字符串(.序号)形式,可以使用\\w+(.\\d+)?

[b]words.conf[/b]

值用冒号分开的,需要作为多个键值对处理,如flight=也不是:衣服,需要解析成flight.1=也不是,flight.2=衣服

[size=medium]方案[/size]

[b]java.util.regex.Pattern[/b]

调用Pattern的compile方法,传入匹配占位符的正则表达式,返回一个Pattern实例。

[b]java.util.regex.Matcher[/b]

调用Pattern实例的matcher方法,传入需要匹配的文本,返回Matcher实例。

接着就可以使用find()遍历所有匹配项,group()返回每个匹配文本,appendReplacement()追加从上一个匹配后开始,到该匹配之间的文本,并替换当前匹配部分,appendTrail()追加从最后一个匹配后开始,到文本结束之间的内容。


[size=medium]代码[/size]


public class CombineTwoFiles {
public static void main(String[] args) throws IOException {
Map<String, String> words = fetchWords(); // 读取键值对

Pattern p = Pattern.compile("\\$\\((\\w+(.\\d)?)\\)"); // 匹配$(qunar)或$(flight.1)

try (BufferedReader reader = new BufferedReader(new InputStreamReader(
CombineTwoFiles.class.getResourceAsStream("context.txt")))) { // JDK7自动资源管理

StringBuffer sb = new StringBuffer();

String line = reader.readLine();
while (line != null) {
Matcher m = p.matcher(line);
while (m.find()) { // 遍历匹配项
String anchor = m.group(1); // group(0)返回整个文本,group(1)返回匹配正则表达式的文本,如果表达式中有括号,返回匹配第一对括号之间表达式的文本
String value = words.get(anchor); //获取键对应的值
if (value == null) { // 值不存在
value = ""; // 赋值为空字符串,防止出现空指针异常
}
m.appendReplacement(sb, value); // 往sb追加自上个匹配后到此次匹配的文本,并将匹配项替换为对应值的文本
}

m.appendTail(sb); // 往sb追加自最后一个匹配后至末尾的文本
line = reader.readLine();
}

System.out.println(sb.toString());
} catch (Throwable t) {
t.printStackTrace();
}
}

private static Map<String, String> fetchWords() throws IOException {
BufferedReader reader = null;
Map<String, String> words = new HashMap<String, String>();

try {
reader = new BufferedReader(new InputStreamReader(CombineTwoFiles.class.getResourceAsStream("word.conf")));
String line = reader.readLine();
while (line != null) {
String[] kv = line.split("=");
if (kv.length == 2) {
String[] vals = kv[1].split(":");
if (vals.length > 1) { // 多个值
int i = 1;
for (String val : vals) {
// 构造形如flight.1的键
words.put(kv[0].concat(".").concat(String.valueOf(i++)), val);
}
} else { // 单个值
words.put(kv[0], kv[1]);
}
}
line = reader.readLine();
}
} finally { // JDK7之前版本,释放资源的方式
if (reader != null) {
reader.close();
}
}
return words;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值