【JAVA】仿顺丰淘宝智能识别信息模块——DidYourTypeItCorrectly

news/2024/11/24 3:30:39/

文章目录

    • 题目
    • 项目层级结构
    • 解答
      • 已完成的部分简介
      • 未完成的部分概述
      • 代码部分
        • DidYourTypeCorrectly.java
        • FormModel.java
        • IntelligentRecognition.java
        • MVCWindow.java
        • Plaint.java
    • 运行结果截图
    • 结语

题目

模拟顺风地址智能识别,对用户输入的信息,包括:姓名、地址、邮政编码、身份证号码、电话号码、电子邮箱等文本信息进行解析,并进行初步的合法性判断。

  • 基础的:文本信息放在文件,代码正确,可扩展性好(考核知识点:面向对象+正则表达式(P233、P285)+I/O+Scanner(P239))
  • 进阶的:界面友好,代码正确,可扩展性好(考核知识点:面向对象+正则表达式(P233、P285)+MVC模式(P298)+Swing+Scanner(P239))

样例视图如下

在这里插入图片描述


项目层级结构


├─.idea
│      .gitignore
│      encodings.xml
│      misc.xml
│      modules.xml
│      uiDesigner.xml
│      workspace.xml
│      
├─out
│  └─production
│      └─DidYourTypeItCorrectly
│              DidYourTypeCorrectly.class
│              FormModel.class
│              icon.png
│              IntelligentRecognition.class
│              MVCWindow.class
│              Plaint$1.class
│              Plaint.class
│              UI.png
│              
└─srcDidYourTypeCorrectly.javaFormModel.javaicon.pngIntelligentRecognition.javaMVCWindow.javaPlaint.javaUI.png

解答

下面简单介绍一下这个项目已完成和未完成的地方~

已完成的部分简介

  1. 友好、黑色简约的UI
    在这里插入图片描述

  2. 可扩展性较好,后续可填加别的字段如银行卡信息等

  3. 使用MVC模式构建(FormModal \ MVCWindow \ IntelligentRecognition)

  4. 代码健壮性良好。用户输入字符串不需要用空格来分割、也不需要使用字段前缀,如姓名张三地址汕头大学等。

  5. 友好的识别提示,用户点击了识别后会在右边出现一个弹框,若右边的属性全部匹配成功则会弹出“成功”否则未“失败”

未完成的部分概述

  1. 使用JavaFx来构建UI页面,JFrame太受局限了,不能在最大程度上优化页面UI
  2. 适用国家仅限中国。若输入英文名、英文的地址、别国的邮编、别国的手机号可能会出现错误。
  3. 未能完全匹配姓名(百家姓的Unicode编码不全)

代码部分

根据上面项目的层级结构一共有5个java源文件,下面将一一展示出来

DidYourTypeCorrectly.java

/** @Author: hiddenSharp429 z404878860@163.com* @Date: 2023-05-17 18:14:42* @LastEditors: hiddenSharp429 z404878860@163.com* @LastEditTime: 2023-06-06 20:35:24* @FilePath: \appe:\java\DidYourTypeItCorrectly\src\FormModel.java* @Description: "Java 作业4-智能识别"*/
import java.awt.*;
public class DidYourTypeCorrectly {public static void main(String[] args) {MVCWindow window = new MVCWindow();//创建窗口window.setVisible(true);//显示窗口}
}

FormModel.java

public class FormModel {String Uname, address, zipCode, identity, phone, email;public FormModel(String Uname, String address, String zipCode, String identity, String phone, String email) {this.Uname = Uname;this.address = address;this.zipCode = zipCode;this.identity = identity;this.phone = phone;this.email = email;}
}

IntelligentRecognition.java

/** @Author: hiddenSharp429 z404878860@163.com* @Date: 2023-05-17 18:08:09* @LastEditors: hiddenSharp429 z404878860@163.com* @LastEditTime: 2023-06-06 20:35:50* @FilePath: \appe:\java\DidYourTypeItCorrectly\src\IntelligentRecognition.java* @Description: ""*/
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.SplittableRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class IntelligentRecognition implements ActionListener {String Input;String Output;String regex;Pattern pattern;Matcher matcher;MVCWindow mvcWindow;FormModel formModel;public static String deleteChars(String input, int startIndex, int endIndex) {StringBuilder stringBuilder = new StringBuilder(input);stringBuilder.delete(startIndex, endIndex + 1);return stringBuilder.toString();}public void setMvcWindow(MVCWindow mvcWindow) {this.mvcWindow = mvcWindow;}public String getUname(String Input) {Output = "";//百家姓的Unicode编码String[] surnames = {"\u795D", // 祝"\u5F20", // 张"\u5B59", // 孙"\u674E", // 李"\u8D75", // 朱"\u90B9", // 马"\u8881", // 宋"\u5929", // 天"\u51AF", // 冯"\u6C88", // 沈"\u8D3E", // 任"\u9EC4", // 黄"\u90D1", // 郑"\u9A6C", // 马"\u6768", // 杨"\u963F", // 阿"\u5434", // 吴"\u5468", // 周"\u5433", // 吴"\u90AC", // 郭"\u7BA1", // 管"\u5B54", // 孙"\u6797", // 林"\u4F55", // 何"\u6731", // 朱"\u9C81", // 谢"\u9648", // 陈"\u8C22", // 谢"\u4F59", // 余"\u6BDB", // 毛"\u82CF", // 苏"\u859B", // 谢"\u6D2A", // 浩"\u8D56", // 赵"\u7F57", // 罗"\u7AA6", // 程"\u9B4F", // 申"\u987E", // 顾"\u9AD8", // 高"\u9F50", // 邓"\u90ED", // 郭"\u5510", // 唐"\u5B5F", // 宋"\u7A0B", // 程"\u738B", // 王"\u8C22", // 谢"\u6C34", // 水"\u9E3F", // 黄"\u5218", // 刘"\u6234", // 戴"\u79E6", // 秦"\u9976", // 龙"\u4FDE", // 俞"\u6881", // 梁"\u9C81", // 谢"\u7A46", // 穆"\u9F9A", // 龚"\u8C2F", // 谯"\u66FE", // 曾"\u6734", // 李"\u8521", // 蔡"\u7AEF", // 端"\u5B8B", // 宋"\u79E6", // 秦"\u6234", // 戴"\u5433", // 吴"\u9C81", // 谢"\u4E8E", // 于"\u5362", // 卢"\u7F57"  // 罗};String regex = "(" + String.join("|", surnames) + ")[\\u4E00-\\u9FA5]{1,2}";pattern = Pattern.compile(regex);matcher = pattern.matcher(Input);while (matcher.find()) {Output = matcher.group();System.out.println(Output);this.Input = deleteChars(Input, matcher.start(), matcher.end() - 1);}return Output;}public String getAddress(String Input) {Output = "";// 中国地址格式:省市区县街道门牌号regex = "([\\u4e00-\\u9fa5]+省)?([\\u4e00-\\u9fa5]+市)?([\\u4e00-\\u9fa5]+区)+([\\u4e00-\\u9fa5]+县)?([\\u4e00-\\u9fa5]+街道)?([\\u4e00-\\u9fa5\\w]+号)?";pattern = Pattern.compile(regex);matcher = pattern.matcher(Input);while (matcher.find()) {Output = matcher.group();System.out.println(Output);this.Input = deleteChars(Input, matcher.start(), matcher.end() - 1);}return Output;}public String getZipcode(String Input) {Output = "";regex = "(10|20|30|40|01|02|03|04|05|06|07|11|12|13|15|16|21|22|23|24|25|27|31|32|33|34|35|36|41|42|43|44|45|46|47|51|52|53|54|55|56|57|61|62|63|64|65|66|67|71|72|73|74|75|81|83|84|85)\\d{4}";pattern = Pattern.compile(regex);matcher = pattern.matcher(Input);while (matcher.find()) {Output = matcher.group();System.out.println(Output);this.Input = deleteChars(Input, matcher.start(), matcher.end() - 1);}return Output;}public String getIdentity(String Input) {Output = "";//中国身份证号码六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码regex = "(1|2|3|4|5|6|8)[1-9]{3}0[1-2]{2}[0-9]{3}[0-1][0-9]{6}(0-9|X)";pattern = Pattern.compile(regex);matcher = pattern.matcher(Input);while (matcher.find()) {Output = matcher.group();System.out.println(Output);this.Input = deleteChars(Input, matcher.start(), matcher.end() - 1);}return Output;}public String getPhone(String Input) {Output = "";regex = "(133|153|180|181|189|177|130|131|132|155|156|185|186|145|176|134|135|136|137|138|139|150|151|152|157|158|159|182|183|184|187|188|147|178|170|171|172|173|174|175|176|177|178|179|166|198|199)\\d{8}";pattern = Pattern.compile(regex);matcher = pattern.matcher(Input);while (matcher.find()) {Output = matcher.group();System.out.println(Output);this.Input = deleteChars(Input, matcher.start(), matcher.end() - 1);}return Output;}public String getEmail(String Input) {Output = "";regex = "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}";pattern = Pattern.compile(regex);matcher = pattern.matcher(Input);while (matcher.find()) {Output = matcher.group();System.out.println(Output);this.Input = deleteChars(Input, matcher.start(), matcher.end() - 1);}return Output;}@Overridepublic void actionPerformed(ActionEvent e) {Input = mvcWindow.textArea.getText();String Uname, address, zipCode, identity, phone, email;/*用正则表达式解析Input字符串输入如:“张三广东省深圳市宝安区西乡街道泰华阳光海hiddensharp@outlook.com1591977326536250120030429481X518102”解析出姓名,地址,邮编,身份证号,电话号码,电子邮箱等信息,顺序可打乱,但是必须包含姓名,地址,邮编,身份证号,电话号码,电子邮箱等信息*/email = getEmail(Input);phone = getPhone(Input);identity = getIdentity(Input);zipCode = getZipcode(Input);Uname = getUname(Input);address = getAddress(Input);checkInfo(Uname,address,zipCode,identity,phone,email);formModel = new FormModel(Uname, address, zipCode, identity, phone, email);mvcWindow.Uname.setText(formModel.Uname);mvcWindow.address.setText(formModel.address);mvcWindow.zipCode.setText(formModel.zipCode);mvcWindow.identity.setText(formModel.identity);mvcWindow.phone.setText(formModel.phone);mvcWindow.email.setText(formModel.email);}public void checkInfo(String Uname,String address,String zipCode,String identity,String phone,String email){//检查信息是否完整if(Uname.equals("")||address.equals("")||zipCode.equals("")||identity.equals("")||phone.equals("")||email.equals("")){JOptionPane.showMessageDialog(null, "信息不完整", "提示", JOptionPane.ERROR_MESSAGE);}else{JOptionPane.showMessageDialog(null, "信息完整", "提示", JOptionPane.INFORMATION_MESSAGE);}}
}

MVCWindow.java

/** @Author: hiddenSharp429 z404878860@163.com* @Date: 2023-05-17 18:07:27* @LastEditors: hiddenSharp429 z404878860@163.com* @LastEditTime: 2023-06-06 20:35:58* @FilePath: \appe:\java\DidYourTypeItCorrectly\src\MVCWindow.java* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE*/import javax.swing.*;
import java.awt.*;public class MVCWindow extends JFrame {FormModel model; // 模型IntelligentRecognition controller; // 控制器JTextArea textArea; // 显示信息JTextField Uname, address, zipCode, identity, phone, email; // 输入的信息JButton button; // 按钮JLabel Title; // 标题JLabel ending; // 结尾int TitleSize = 50; // 标题大小int ItemSize = 20; // 输入框大小Font TitleFont = new Font("微软雅黑", Font.BOLD, TitleSize); // 标题字体Font ItemFont = new Font("微软雅黑", Font.PLAIN, ItemSize); // 输入框字体MVCWindow() {init();}void init() {// 设置窗口setTitle("智能识别系统");// 设置标题setBackground(Color.WHITE);setBounds(100, 100, 1000, 700);// 设置窗口大小setIconImage(getToolkit().getImage("src/icon.png"));setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 设置关闭窗口时的操作setResizable(false);// 设置窗口不可改变大小// 设置组件Title = new JLabel("智能识别系统");Title.setFont(TitleFont);textArea = new JTextArea(17, 14);textArea.setLineWrap(true);// 自动换行Uname = new JTextField(15);address = new JTextField(15);zipCode = new JTextField(15);identity = new JTextField(15);phone = new JTextField(15);email = new JTextField(15);button = new JButton("识别");// 设置布局setLayout(new BorderLayout());// 设置标题面板JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER));titlePanel.setBackground(Color.DARK_GRAY);titlePanel.add(Title);titlePanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1, true));add(titlePanel, BorderLayout.NORTH);// 设置表单面板JPanel formPanel = new JPanel(new GridBagLayout());formPanel.setBackground(Color.WHITE);GridBagConstraints gbc = new GridBagConstraints();gbc.gridx = 0;gbc.gridy = GridBagConstraints.RELATIVE;gbc.anchor = GridBagConstraints.WEST;gbc.insets = new Insets(5, 5, 5, 5);// 设置输入面板JPanel inputPanel = new JPanel(new BorderLayout());textArea.setBackground(Color.WHITE);textArea.setFont(ItemFont);textArea.setToolTipText("显示识别结果");inputPanel.add(textArea, BorderLayout.NORTH);inputPanel.add(button, BorderLayout.SOUTH);inputPanel.setBackground(Color.WHITE);add(inputPanel, BorderLayout.WEST);formPanel.add(new JLabel("姓名"), gbc);formPanel.add(Uname, gbc);formPanel.add(new JLabel("地址"), gbc);formPanel.add(address, gbc);formPanel.add(new JLabel("邮编"), gbc);formPanel.add(zipCode, gbc);formPanel.add(new JLabel("身份证号"), gbc);formPanel.add(identity, gbc);formPanel.add(new JLabel("电话号码"), gbc);formPanel.add(phone, gbc);formPanel.add(new JLabel("电子邮箱"), gbc);formPanel.add(email, gbc);add(formPanel, BorderLayout.EAST);// 设置中间面板Plaint plaint = new Plaint();plaint.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1, true));add(plaint, BorderLayout.CENTER);// 设置页底面板JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));bottomPanel.setBackground(Color.DARK_GRAY);ending = new JLabel("Author: hiddensharp");ending.setFont(new Font("微软雅黑", Font.PLAIN, 15));ending.setForeground(Color.WHITE);ending.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1, true));bottomPanel.add(ending);add(bottomPanel, BorderLayout.SOUTH);// 设置字体颜色Title.setForeground(Color.WHITE);button.setForeground(Color.BLACK);Uname.setForeground(Color.BLACK);address.setForeground(Color.BLACK);zipCode.setForeground(Color.BLACK);identity.setForeground(Color.BLACK);phone.setForeground(Color.BLACK);email.setForeground(Color.BLACK);// 设置输入框样式Uname.setFont(ItemFont);address.setFont(ItemFont);zipCode.setFont(ItemFont);identity.setFont(ItemFont);phone.setFont(ItemFont);email.setFont(ItemFont);// 设置按钮样式button.setBackground(Color.WHITE);button.setFocusPainted(false);button.setPreferredSize(new Dimension(100, 50));ImageIcon buttonIcon = new ImageIcon("src/icon.png");Image buttonIconImage = buttonIcon.getImage();Image scaledImage = buttonIconImage.getScaledInstance(50, 50, Image.SCALE_SMOOTH);buttonIcon = new ImageIcon(scaledImage);button.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1, true));button.setIcon(buttonIcon);button.setFont(new Font("微软雅黑", Font.BOLD, 20));button.setIconTextGap(100);// 创建控制器controller = new IntelligentRecognition();// 添加监听器button.addActionListener(controller);// 设置控制器的视图controller.setMvcWindow(this);}
}

Plaint.java

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
/*author:命运的信徒* date:2019.7.18* arm:java动态绘图的方法*/
public class Plaint extends JPanel {private List<Integer> values;                      // 存储数据的集合,线程不安全private static final int MAX_VALUE = 200;          // 最大值(限制里面的y数据)private static final int MAX_COUNT_OF_VALUES = 50; // 集合的最大容量public Plaint() {//一个线程安全的集合values = Collections.synchronizedList(new ArrayList<Integer>());// 使用线程的目的,动态的,可以往集合里面添加和去除数据new Thread(new Runnable() {public void run() {//一个随机数,准确的说是小于200的Random rand = new Random();try {while (true) {//生成的数添加集合,如果集合里面的数据多了就剔除数据addValue(rand.nextInt(MAX_VALUE)); // 产生一个数据,并模拟接收并放到容器里.//这个是一个重绘的方法,是线程安全的;可以调用paintComponent(Graphics g) 方法repaint();Thread.sleep(100);}} catch (InterruptedException e) {e.printStackTrace();}}}).start();}@Overridepublic void paintComponent(Graphics g) {super.paintComponent(g);
//准备绘制Graphics2D g2d = (Graphics2D) g;
//设置绘制线条的质量g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//设置宽高int w = getWidth();int h = getHeight();
//设置x轴方向的单位长度;如果宽400px,设置最大的数据容量是50;那么一个数据就占据8pxint xDelta = w / MAX_COUNT_OF_VALUES;
//这个是集合的实时长度,肯定是小于或等于MAX_COUNT_OF_VALUESint length = values.size();
//对集合里面的数据进行绘制,第一个点和第二个点要连线for (int i = 0; i < length - 1; ++i) {/** x轴的位置:xDelta * (MAX_COUNT_OF_VALUES - length + i)  如果集合的数据没有溢出来,一定是最后一个是最右边,第一个是集合的最大长度-集合当前长度+1;* y轴的位置:normalizeValueForYAxis(values.get(i), h)* 前一个数据和后一个数据相连接*/g2d.drawLine(xDelta * (MAX_COUNT_OF_VALUES - length + i), normalizeValueForYAxis(values.get(i), h),xDelta * (MAX_COUNT_OF_VALUES - length + i + 1), normalizeValueForYAxis(values.get(i + 1), h));}}/*** 接收到的数据放入内存.* @param value*/private void addValue(int value) {// 循环的使用一个接收数据的空间.// 最好是实现一个循环数组,而不是偷懒的使用ArrayList.if (values.size() > MAX_COUNT_OF_VALUES) {values.remove(0);}values.add(value);}/*** 规一化y轴方向的值. 使得value在y轴的值为[0, height]之间.*/private int normalizeValueForYAxis(int value, int height) {return (int) ((double) height / MAX_VALUE * value);}private static void createGuiAndShow() {//窗体的名称JFrame frame = new JFrame("java动态绘制图形");//内容frame.getContentPane().add(new Plaint());//设置关闭窗体就是关闭整个程序frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体的大小frame.setSize(600, 600);frame.setLocationRelativeTo(null);//设置窗体可见frame.setVisible(true);}
//
//    public static void main(String[] args) {
//        createGuiAndShow();
//    }
}

运行结果截图

由于涉及个人隐私部分图片的相关文字打上了马赛克
在这里插入图片描述
图片1说明:输入字符串后识别成功

在这里插入图片描述
图片2说明:识别成功后右边自动填写相关的属性

在这里插入图片描述
图片3说明:更换顺序仍旧识别成功

在这里插入图片描述图片4说明:缺少属性识别失败

在这里插入图片描述
图片5说明:将未识别到的属性列置空,其他的照填


结语

如果有疑问欢迎大家留言讨论,你如果觉得这篇文章对你有帮助可以给我一个免费的赞吗?我们之间的交流是我最大的动力!


http://www.ppmy.cn/news/849340.html

相关文章

基于 FPGA 的 HDMI/DVI 显示

文章目录 前言一、HDMI 与 DVI 的区别与联系1.1 DVI 接口含义1.2 HDMI 接口含义1.3 HDMI 与 DVI 的区别1.4 HDMI 与 DVI 的兼容性1.5 HDMI 与 DVI 接口对比 二、DVI 数据链路介绍2.1 输入接口层2.2 TMDS 发送器2.3 TMDS 接收器2.4 输出接口层 三、传输原理与实现3.1 TMDS原理3.…

苹果APP安装包ipa如何安装在手机上

苹果APP的安装比安卓复杂且困难&#xff0c;很多人不知道如何将ipa文件安装到手机上。以下是几种苹果APP安装在iOS设备的方式&#xff0c;供大家参考。 一、上架App Store 这是最正规的方式。虽然审核过程复杂、时间较长&#xff0c;且审核条件较为苛刻&#xff0c;但借助第三…

Unity基于C#事件委托机制

事件委托是一种用于实现观察者模式的设计模式&#xff0c;它允许对象在发生特定事件时通知其他对象。在Unity中&#xff0c;事件委托机制为开发者提供了一种简单而有效的方式来处理游戏中的事件和交互。 对啦&#xff01;这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的…

高速入门知识02:降低串扰和维持信号完整性的布线方法

文章目录 前言一、单端走线布线1.1.带有短截线的菊花链布线1.2.没有短截线的菊花链布线1.3.星型布线1.4.蛇型布线 二、差分走线布线 前言 串扰是并行走线间不需要的信号耦合。微带线和带状线正确的布线和叠层布局能够降低串扰。 双带线布局有两个靠近的信号层&#xff0c;为降…

Rogue DHCP Server攻击(仿冒DHCP Server攻击)

目录 事件原理 DHCP 仿冒攻击 防护方法 事件原理 攻击原理:攻击者仿冒DHCP Server向客户端分配错误的IP地址以及错误的网关等信息,导致用户无法正常的访问网络。漏洞分析:DHCP客户端收到DHCP Server的DHCP消息之后,无法区分这些DHCP消息是来自仿冒的DHCP Server还是…

希捷撤离 硬盘的那些风花雪月记忆

小刀马 曾几何时&#xff0c;希捷&#xff0c;西部数据&#xff0c;三星&#xff0c;东芝、富士通&#xff0c;这些硬盘品牌都是非常流行的&#xff0c;而自己拥有的第一部硬盘也是希捷&#xff0c;那时候记得是600MB&#xff0c;但是价格也是1千多了&#xff0c;后来慢慢的PC都…

拍立淘-图像搜索与识别

云栖 TechDay40 期&#xff0c;阿里巴巴 iDST 视觉技术总监启磐来给大家分享图像搜索和识别。本文主要从 iDST 和拍立淘业务开始谈起&#xff0c;接着分析了拍立淘技术框架&#xff0c;着重分析了拍立淘核心技术&#xff0c;最后展示了呈现效果和云服务。 移动端的以图搜图是一…

日语_随笔记

模仿 实践 反思 笔记本自带键盘 禁用 在cmd中输入语句&#xff1a; sc config i8042prt start disabled &#xff0c;回车运行成功后重启 如果想要再次启用笔记本的自带键盘&#xff0c;只需在cmd中执行语句&#xff1a;sc config i8042prt start auto &#xff0c;然后重启电…