黑马程序员——正则表达式(2)自制模糊查询

黑马官方提供的tlias智能学习辅助系统接口文档 阅读详情
------- android培训java培训、期待与您交流! ----------

正则表达式30分钟入门教程


这次写的这段代码是关键字模糊查询。Steam上有许多游戏。用户输入一段查询文字,然后程序会比较所有保存的条目的键,将符合查询内容的条目按照相关度从大到小打印出来。

如果输入的查询内容没有有效字符则提示信息不进行查询。

如果输入的查询内容没有匹配的条目,也会给出提示。

因为网页还不是很懂,所以是将网页上的内容直接复制到本地txt。然后读取文档将游戏信息抽出封装成对象,再添加到集合中。后期学会如何读取网页信息后就可以实现实时查询了!

其实想做的是将所有匹配的结果列出后用户可以点击选择自己想要查询的游戏,然后再显示出这个游戏的相关信息。目前能想到的是将匹配的结果做成Label显示在窗体上,当用户点击某个Label就表示这个Label是用户想要的结果。然后再返回游戏信息。


/**
 * 需求:模糊查询游戏名
 * 输入:用户输入查询内容
 * 输出:按照相关度从高到低排列的查询结果
 * 数据来源:http://www.steamcardexchange.net/index.php?badgeprices。为简化,目前是将此页面信息复制到本地TXT。内容格式如下:
0RBITALIS	6	0.97 
1... 2... 3... KICK IT! (Drop That Beat Like an Ugly Baby)	6	1.15 
1Heart	6	1.63 
1Quest	6	0.63 
 *游戏名\t卡牌数\t徽章价格\r\n 
 * 
 * 步骤:
 * 0.为了保存游戏卡牌信息建立一个Card类	有三个字段存放信息:private String name;private int num;private double setPrice;
 * 1.加载“数据库”:
 * 1)输入:文件 FileReader,为了方便读取,使用BufferedReader.
 * 2)用split("\t")分割每行内容并保存在一个TreeMap中。key=游戏名。value=Card对象。
 * 2.用户输入查询内容。为了简化,这里暂时是代码里输入了一个具有代表性的查询内容。
 * 3.处理用户输入的内容。为了实现模糊查询,我使用了以下方法: 
 * 1)将输入拆分成单词。然后每个拆出的单词都作为正则表达式去和“数据库”的键进行匹配。使用表达式:"\\b\\w+\\b"
 * 2)拆分的原则是a.单词b.去掉特殊符号。像"aasd121da asd31 a412a !ar3@ #3! @13fa 133# !a@b#"这段文字,可以拆出aasd121da,asd31,a412a,ar3,3,13fa,133,a,b这几个单词。
 * 	  c.考虑到1个字符去比较是比较没有意义的事情,所以只保留2个字符以上的单词。比如"!a@b#"虽然能匹配出a,b但是因为是单字符,所以这两个都抛弃。
 * 3)将结果保存进一个ArrayList<String>中。如果列表长度为0,则说明没有有效输入,这时候就不要再浪费资源进行下一步,直接提示输入无效后返回。
 * 4.建立一个保存匹配结果的TreeMap<String,Integer>,String代表KEY,Integer标记这个键被匹配到的次数(单词可能有多个)。次数越多表示相关性越大。
 * 5.将每个捕获的单词都作为表达式,在循环中与数据库的keySet()进行匹配,每当匹配到一个新的KEY就添加到保存匹配结果的Map中。每当匹配到一个结果中已存在的KEY,就取出其标记次数,并+1后再存入。
 * 6.如果TreeMap<String,Integer>的大小为0说明没有匹配结果,就给用户提示然后返回,不要浪费资源进行下一步。
 * 7.将这个TreeMap的entrySet()转换成一个ArrayList<Map.Entry<String,Integer>>,然后用Collections。sort(list,comparator)进行排序。排序方法用自定义的比较器制定:按照Value值大小降序排序。打印出来。
 * 
 */
package test;
import java.io.*;
import java.util.*;
import java.util.regex.*;
class Card// 此类在此不是重点。不讨论
{
	private String name;
	private int num;
	private double setPrice;
	private double avrValueInUSD;
	private double avrValueInCNY;

	public Card(String name, int num, double setPrice) {
		super();
		this.name = name;
		this.num = num;
		this.setPrice = setPrice;
		calVal();
	}

	@Override
	public String toString() {
		return "Card [name=" + name + ", num=" + num + ", setPrice=" + setPrice
				+ "]";
	}

	public String getName() {
		return name;
	}

	public int getNum() {
		return num;
	}

	public double getSetPrice() {
		return setPrice;
	}

	private void calVal() {
		double obtain = Math.ceil(num / 2);
		avrValueInUSD = setPrice / num * obtain - obtain * 0.02;
		avrValueInCNY = avrValueInUSD * 6.25;
	}
}

public class TestStringSearch {

	public static void main(String[] args) throws Exception {
		TreeMap<String, Card> tm = (TreeMap<String, Card>) loadData();
		// testRegex();
		// search for the game: //N.P.P.D.RUSH// - The milk of Ultra violet
		search("NPPD.RUSH The milk of Ultra violet", tm.keySet());		
		// search("!@#99!@# !@#!@#",tm.keySet());
	}

	private static void search(String inputWords, Set<String> dbSet) {

		// 切割用户的查询内容,将之按照单词划分出来。
		// String
		// input="//N.P.P.D.RUSH// - The milk of Ultra violet"/*"aasd121da asd31 a412a !ar3@ #3! @13fa 133# !a@b#"*/;
		// String regex="\\b[.\\w]+\\b";//这个式子可以匹配出N.P.P.D.RUSH
		String regex = "\\b\\w+\\b";// 这个式子可以匹配出RUSH
		Pattern p4Regex = Pattern.compile(regex);
		Matcher m4Regex = p4Regex.matcher(inputWords);
		// 将查询单词存入表达式列表中。
		ArrayList<String> regexList = new ArrayList<String>();
		String tmp = null;
		while (m4Regex.find()) {
			tmp = m4Regex.group();
			if (tmp.length() > 1) {// 当匹配结果的长度只有1,就是1个字母,拿1个字母去做表达式,结果太模糊。所以放弃。之所以会做这个判断是因为有的游戏名包含//N.P.P.D.RUSH//
				// System.out.println(tmp);
				regexList.add(tmp);
			}
		}
		// 如果有效单词结果为0就不要再去查询“数据库”了,提示信息后直接返回即可。
		if (0 == regexList.size()) {
			System.out.println("InValid words with your search:\"" + inputWords
					+ "\".");
			return;
		}

		// 将所有和查询单词匹配的键全部存入匹配结果的MAP中。并为每个键维护一个int数值,标记键与查询单词匹配的次数。
		TreeMap<String, Integer> matchResults = new TreeMap<String, Integer>();
		int cntInputs = regexList.size();
		Pattern p4Search = null;
		Matcher m4Search = null;
		while (0 < cntInputs--) {
			for (String input : dbSet) {
				p4Search = Pattern.compile(regexList.get(cntInputs),
						Pattern.CASE_INSENSITIVE);// 忽略大小写
				m4Search = p4Search.matcher(input);
				if (m4Search.find()) {
					if (matchResults.containsKey(input))// 如果已存入,则取出标记次数并+1再存回去。
					{
						matchResults.put(input, matchResults.get(input) + 1);
					} else {// 如果没存入则新增一个条目
						matchResults.put(input, 1);
					}
				}
			}
		}
		// 如果查询结果为0,提示信息后直接返回即可。
		if (0 == matchResults.size()) {
			System.out.println("Could not find the result with your search:\""
					+ inputWords + "\".");
			return;
		}

		// 将匹配结果按照标记次数排列,已备之后由用户选择匹配出的结果。
		// 也就是把MAP按照value降序排列
		// 先将map的条目转换成list
		List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(
				matchResults.entrySet());
		// 用sort排序,自定义一个比较器
		Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
			@Override
			// 让value大的排在前面。
			public int compare(Map.Entry<String, Integer> arg0,
					Map.Entry<String, Integer> arg1) {
				return arg1.getValue().compareTo(arg0.getValue());
			}
		});

		System.out.println("There are " + list.size()
				+ " results match your search \"" + inputWords + "\":");
		int cntResults = 0;
		for (Map.Entry<String, Integer> me : list) {
			System.out.println((++cntResults) + ":\t[" + me.getKey()
					+ "]......with [" + me.getValue() + "] relevance.");
			// 为了控制输出内容的数量,可以做个限制
			if (10 <= cntResults) {
				System.out.println("Other results have less relevance.");
				break;
			}
		}

	}

	private static void testRegex() {
		String input = "//N.P.P.D.RUSH// - The milk of Ultra violet"/* "aasd121da asd31 a412a !ar3@ #3! @13fa 133# !a@b#" */;
		// String regex="\\b[.\\w]+\\b";//这个式子可以匹配出N.P.P.D.RUSH
		String regex = "\\b\\w+\\b";// 这个式子可以匹配出RUSH
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(input);
		while (m.find()) {
			String tmp = m.group();
			if (tmp.length() > 1) {// 当匹配的长度只有1,就是1个字母,拿1个字母去做表达式,结果太模糊。所以放弃。之所以会做这个判断是因为有的游戏名包含//N.P.P.D.RUSH//
				System.out.println(tmp);
			}
		}
	}

	private static Map loadData() throws Exception {
		File file = new File(
				"G:\\Codes\\Language\\JAVA\\Project\\Study_Prime\\steam",
				"db.txt");
		TreeMap<String, Card> tm = new TreeMap<String, Card>();

		BufferedReader bin = new BufferedReader(new FileReader(file));
		String tmpLine = null;
		String[] results = null;
		// Sleeping Dogs™这种有特殊字符的需要处理
		while (null != (tmpLine = bin.readLine())) {
			results = tmpLine.split("\t");
			tm.put(results[0],
					new Card(results[0], Integer.parseInt(results[1]), Double
							.parseDouble(results[2])));
		}

		bin.close();

		return tm;
	}
}

运行结果:

There are 343 results match your search "NPPD.RUSH The milk of Ultra violet":
1: [//N.P.P.D.RUSH// - The milk of Ultra violet]......with [6] relevance.
2: [9 Clues: The Secret of Serpent Creek]......with [2] relevance.
3: [Abyss: The Wraiths of Eden]......with [2] relevance.
4: [Adventure Time: The Secret Of The Nameless Kingdom]......with [2] relevance.
5: [Alex Hunter - Lord of the Mind]......with [2] relevance.
6: [Beatbuddy: Tale of the Guardians]......with [2] relevance.
7: [Blood of the Werewolf]......with [2] relevance.
8: [Call of Cthulhu: The Wasted Land]......with [2] relevance.
9: [Crypt of the NecroDancer]......with [2] relevance.
10: [Defender's Quest: Valley of the Forgotten]......with [2] relevance.
Other results have less relevance.



tlias智能学习辅助系统-增删改查 本篇实现黑马tlias智能学习辅助系统中的部门以及员工管理,主要完成增删改查操作,后面会进一步总结登录校验、异常处理以及AOP的内容。 阅读详情

相关推荐

A股历史数据免费下载终极指南:4000+个股数据一键打包获取

本文提供了获取A股历史数据的完整免费方案,重点介绍了Tushare Pro、AkShare等开源金融数据API的使用方法。通过详细的Python脚本示例,指导读者如何自动化批量抓取、清洗、存储4000多只个股的历史行情数据,并分享数据质量校验与性能优化技巧,助力量化研究与市场分析。

ooo22的博客 1669

实时搜索(模糊查询).html

实时搜索,就是利用字符串的indexOf方法进行模糊查询,很简单的一种,之前的demo,希望你们有用!

28-Halcon-- union_object_model_3d函数功能(用于3D模型融合)

Halcon算子union_object_model_3d是专业的3D模型融合工具,主要用于多视图拼接、部件组装和多源数据融合。该算子支持点云、网格和参数化模型输入,提供多种融合算法选择,包括基础点云拼接('points_cloud')、网格融合('mesh')和精确CAD布尔运算('cad')。工业应用涵盖逆向工程扫描拼接、汽车部件虚拟装配等场景,支持性能优化如空间分区和流式处理。算子还解决颜色属性融合、法向量保留等特殊需求,并提供拼接误差分析、拓扑验证等质量评估手段。最佳实践包含动态场景重建工作流和CA

weixin_45590420的博客 1026

正则表达式-模糊查询

使用正则表达式模糊查询时,使用如下格式: .*?匹配内容.*

qq_38914978的博客 4790

在Sakura编辑器中搜索控制代码(NULL等)置换删除方法

补足>类似上述的正则表达式有“\xHH”,这是多字节字符用的,如果指定控制代码,会出错,所以不能使用。要在Sakura编辑器中搜索控制代码(控制字符),请使用正则表达式中的“\x{HHHH}”用就可以了。(必须包含正则表达式库“bregonig.dll”)例如:删除NULL(0x00)时。

ta_ng的博客 538

大数据:模糊查询LIKE和正则RLIKE,REGEXP

模糊查询LIKE和正则RLIKE,REGEXP

weixin_63058507的博客 9084

html模糊搜索怎么实现,前端模糊搜索,如何实现从头开始检索?

如图,我想要实现下面的效果如何限定只从头部开始搜索呢?我现在使用的search直接进行搜索匹配,会出现下面的情况可是我希望限定只从头部开始搜索,应该如何优化修改代码?let arr = [] // 搜索结果列表if (this.isNumStart) { // 股票代码搜索this.searchDataStk.map(item => {if (item.code.search(this...

weixin_28885791的博客 495

javaWeb06:模糊查询&评论&include指令

一、模糊查询 代码展示:admin界面 <form action="/web05/news/admin.jsp" method="post"> <select name="type"> <option value='nauthor'>作者</option> <option value='ntitle'>标题</option> </selecte> <input...

weixin_62735525的博客 298

SpringBoot SpringBoot 开发实用篇 4 数据层解决方案 4.10 MongoDB 基础操作

SpringBoot SpringBoot 开发实用篇 4 数据层解决方案 4.10 MongoDB 基础操作

代码改变世界 400

视频教程-SpringMVC+Spring+Mybatis[SSM三大框架综合练习]-Java

SpringMVC+Spring+Mybatis[SSM三大框架综合练习] ...

weixin_27637809的博客 209

数据库测试开发工程师面经

面试了一个数据库测试,整体感觉自己的学习情况不够扎实,会做过程性的东西,却不扎实不了解底层原理,需要查漏补缺,多思考。

m0_63248250的博客 1061

正则表达式笔记

1.正则表达式是使用单个字符串来描述匹配一系列符合某个句法规则的字符串。比如查找以http开图以jpg结尾的字符串。2.是对字符串操作的一种逻辑公式。3.处理文本和数据.4.正则表达式过程:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;否则匹配失败。5.需要在开头引入 import re6.正则表达式语法   -----使用正则表达式匹配单个字符。7.使用正则表达式表示多个...

tamakisakura 658

基于jQuery的使用Ajax动态执行模糊查询功能

一个好的心态和一个坚持的心很重要,很多冲着高薪的人想学习前端,但是能学到最后的没有几个,遇到困难就放弃了,这种人到处都是,就是因为有的东西难,所以他的回报才很大,我们评判一个前端开发者是什么水平,就是他解决问题的能力有多强。分享一些简单的前端面试题以及学习路线给大家,狂戳这里即可获取解视频,并且会持续更新!**如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)一个好的心态和一个坚持的心很重要。

2401_84093899的博客 388

html5 带模糊查询的datalist标签

&lt;input type="text" list="car" /&gt;  &lt;!--普通输入框,通过list属性绑定数据列表--&gt;     &lt;datalist id="car"&gt;    &lt;!--数据列表标签--&gt;         &lt;option&gt;1宝马&lt;/option&gt;   &lt;

2088

html搜索内容要使用方法,使用jquery对html内容进行跨标签的关键词检索

本人后端狗,接触过一些html、javascript,这个问题是组内前端小伙伴遇到的,帮他解决了这个问题问题描述:将word文件转为html后在页面显示,需要对这部分html内容进行关键词搜索高亮,但转换后的文字被拆分,被包含在各种标签里,很多内容检索不到。解决过程如下:直接对html片段使用模糊匹配*关键词在同一个标签内有效-关键词被拆分到不同标签里,页面上可以看到这个关键词,但是搜索不到-误匹...

weixin_39566864的博客 471

黑马旅游网项目日志(二)激活与登录功能

黑马旅游网项目日志(二)搜素与分页功能 最近在赶课程设计,终于弄完了,把未完成的功能继续完成。 1.邮件激活功能 为了防止用户填虚假信息,在user里设置一个表示激活状态的属性status,必须使用邮件激活,将激活状态从默认的“N”改为“Y”才可以使注册的用户名有效。具体实现的步骤如下: (1)在注册功能的regist方法保存用户信息后,调用java中的mail类的方法一个sendmail方法,往注册的邮箱地址发送激活邮件。注意:发件人的邮箱必须开启SMTP协议,同意第三方客户端访问邮箱功能,要不然id

hxmagic的博客 1067

Mybatis(黑马程序员

性能更高更安全(防止SQL注入)性能更高:预编译SQL,编译一次之后会将编译后的SQL语句缓存起来,后面再次执行这条语句时,不会再次编译。(只是输入的参数不同)更安全(防止SQL注入):将敏感字进行转义,保障SQL的安全性。在页面原型中,列表上方的条件是动态的,是可以不传递的,也可以只传递其中的1个或者2个或者全部。而在我们刚才编的SQL语句中,我们会看到,我们将三个条件直接死了。如果页面只传递了参数姓名name 字段,其他两个字段 性别 和 入职时间没有传递,那么这两个参数的值就是null。

weixin_62646853的博客 1104

数据库-多表查询

数据库-多表查询

m0_63949203的博客 1496

黑马-“tlias智能学习辅助系统” 项目 复盘

学习java将近一年了,看javaweb过程中首次接触完整的前后端结合项目,看完一遍黑马的课,还有点迷糊,感觉自己什么都没学会,下面对这个项目进行一下完整的梳理和复盘。

一位努力搬砖的不入流程序猿 4494

罗技键鼠老版本软件驱动Logitech 9.2.65.0.zip

windows上用的GHUB老版本驱动,exe格式

上一篇: 黑马程序员——GUI(1)基本窗体组件
下一篇: 黑马程序员——正则表达式(1)
rexih
博客等级 码龄12年 0粉丝 47原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值