java用正则表达式判断一个18位身份证号是不是有效
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java用正则表达式判断一个18位身份证号是不是有效相关的知识,希望对你有一定的参考价值。
package homework;import java.util.Scanner;public class Homework public static void main(String[] args) String regex="([1-9]\\d17)|([1-9]\\d16x"; System.out.println("请输入18位的身份证号码:"); Scanner scanner=new Scanner(System.in); String s=scanner.nextLine(); if(s.matches(regex)) int y1,y2; String year1=s.substring(6, 8); y1=Integer.parseInt(year1); String year2=s.substring(8, 10); y2=Integer.parseInt(year2); if((y1==18&&y2>=87&&y2<=89)||(y1==19&&y2>=0&&y2<=99)||(y1==20&&y2<=17)) int m,d; String month=s.substring(10, 12); m=Integer.parseInt(month); String day=s.substring(12, 14); d=Integer.parseInt(day); if((m==1||m==3||m==5||m==7||m==8||m==10||m==12)&&(d==31)) System.out.println("有效"); else if((m==4||m==6||m==9||m==11)&&(d==30)) System.out.println("有效"); else if(m==2) int y; String year=s.substring(6, 10); y=Integer.parseInt(year); if(((y%4==0&&y%100!=0)||y%400==0)&&(d==29)) System.out.println("有效"); else if(((y%4!=0&&y%100==0)||y%400!=0)&&(d==28)) System.out.println("有效"); else System.out.println("无效"); return; else System.out.println("无效"); return; int ss; String sex=s.substring(16, 17); ss=Integer.parseInt(sex); if(ss%2==0) System.out.println("女性"); else System.out.println("男性"); else System.out.println("无效"); else System.out.println("无效"); 程序如上,,但是无法正常运行。想知道问题在哪?
很显然 是你得正则表达式不对啊,正确的18位身份证验证正则为:
String regex = "^[1-9]\\\\d5(18|19|([23]\\\\d))\\\\d2((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\\\d3[0-9Xx]$";而且就算正则表达式正确了,你的逻辑判断代码也是有问题,
完成代码如下,请参考:
public class Homeworkpublic static void main(String[] args)
String regex = "^[1-9]\\\\d5(18|19|([23]\\\\d))\\\\d2((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\\\d3[0-9Xx]$";
System.out.println("请输入18位的身份证号码:");
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
if (s.matches(regex))
int y1, y2;
String year1 = s.substring(6, 8);
y1 = Integer.parseInt(year1);
String year2 = s.substring(8, 10);
y2 = Integer.parseInt(year2);
if ((y1 == 18 && y2 >= 87 && y2 <= 89)
|| (y1 == 19 && y2 >= 0 && y2 <= 99)
|| (y1 == 20 && y2 <= 17))
int m, d;
String month = s.substring(10, 12);
m = Integer.parseInt(month);
String day = s.substring(12, 14);
d = Integer.parseInt(day);
if ((m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12)
&& (d == 31))
System.out.println("有效");
else if ((m == 4 || m == 6 || m == 9 || m == 11) && (d == 30))
System.out.println("有效");
else if (m == 2)
int y;
String year = s.substring(6, 10);
y = Integer.parseInt(year);
if (((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)
&& (d == 29))
System.out.println("有效");
else if (((y % 4 != 0 && y % 100 == 0) || y % 400 != 0)
&& (d == 28))
System.out.println("有效");
else
System.out.println("无效");
return;
else
System.out.println("无效");
return;
int ss;
String sex = s.substring(16, 17);
ss = Integer.parseInt(sex);
if (ss % 2 == 0)
System.out.println("女性");
else
System.out.println("男性");
else
System.out.println("无效");
else
System.out.println("无效");
追问
那个正则表达式开头的^和结尾的$有什么作用啊?是必须要的嘛?
追答^表示开始,$表示结束,另外我看了你以往问问题,我发现 你问玩问题都是从不采纳的吗?
追问不用^和$也是可以的。。虽然你语气不太好但是还是很感谢你。问过的问题有用的回答都采纳了,没采纳的是因为并没有解决我的疑问。请不要断章取义
参考技术A 你这不是身份证的正则,这正则也太随意了,【1-9】没问题,但\d17有问题,\d是0-9的数字,但身份证的第7位开始就是出生日期,第7位8位肯定是19或20,接的几位也有限定,但你一个\d完全没有限定值,出生日期0000也可以取到。/^[1-9][0-9]5(19|20)[0-9]2((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|31)|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]3([0-9]|x|X)$/追问
我写的很简单,但是我下面有进行判断的。不过还是很感谢你
参考技术B d16x" 这里引号前少了个) 参考技术C 杂诗(佚名) 参考技术D isIDCard2=/^[1-9]\d5[1-9]\d3((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d3([0-9]|X)$/;Java笔试题之《算法与编程》
算法与编程
1.判断身份证:要么是15位,要么是18位,最后一位可以为字母,并写程序提出其中的年月日。
答:我们可以用正则表达式来定义复杂的字符串格式,(\\d{17}[0-9a-zA-Z]|\\d{14}[0-9a-zA-Z])可以用来判断是否为合法的15位或18位身份证号码。
因为15位和18位的身份证号码都是从7位到第12位为身份证为日期类型。这样我们可以设计出更精确的正则模式,使身份证号的日期合法,这样我们的正则模式可以进一步将日期部分的正则修改为[12][0-9]{3}[01][0-9][123][0-9],当然可以更精确的设置日期。
在jdk的java.util.Regex包中有实现正则的类,Pattern和Matcher。以下是实现代码:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexTest {
/**
* @param args
*/
public static void main(String[] args) {
// 测试是否为合法的身份证号码
String[] strs = { "130681198712092019", "13068119871209201x",
"13068119871209201", "123456789012345", "12345678901234x",
"1234567890123" };
Pattern p1 = Pattern.compile("(\\\\d{17}[0-9a-zA-Z]|\\\\d{14}[0-9a-zA-Z])");
for (int i = 0; i < strs.length; i++) {
Matcher matcher = p1.matcher(strs[i]);
System.out.println(strs[i] + ":" + matcher.matches());
}
Pattern p2 = Pattern.compile("\\\\d{6}(\\\\d{8}).*"); // 用于提取出生日字符串
Pattern p3 = Pattern.compile("(\\\\d{4})(\\\\d{2})(\\\\d{2})");// 用于将生日字符串进行分解为年月日
for (int i = 0; i < strs.length; i++) {
Matcher matcher = p2.matcher(strs[i]);
boolean b = matcher.find();
if (b) {
String s = matcher.group(1);
Matcher matcher2 = p3.matcher(s);
if (matcher2.find()) {
System.out.println("生日为" + matcher2.group(1) + "年"
+ matcher2.group(2) + "月"
+ matcher2.group(3) + "日");
}
}
}
}
}
2、编写一个程序,将a.txt文件中的单词与b.txt文件中的单词交替合并到c.txt文件中,a.txt文件中的单词用回车符分隔,b.txt文件中用回车或空格进行分隔。
答:
package cn.itcast;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class MainClass{
public static void main(String[] args) throws Exception{
FileManager a = new FileManager("a.txt",new char[]{\'\\n\'});
FileManager b = new FileManager("b.txt",new char[]{\'\\n\',\' \'});
FileWriter c = new FileWriter("c.txt");
String aWord = null;
String bWord = null;
while((aWord = a.nextWord()) !=null ){
c.write(aWord + "\\n");
bWord = b.nextWord();
if(bWord != null)
c.write(bWord + "\\n");
}
while((bWord = b.nextWord()) != null){
c.write(bWord + "\\n");
}
c.close();
}
}
class FileManager{
String[] words = null;
int pos = 0;
public FileManager(String filename,char[] seperators) throws Exception{
File f = new File(filename);
FileReader reader = new FileReader(f);
char[] buf = new char[(int)f.length()];
int len = reader.read(buf);
String results = new String(buf,0,len);
String regex = null;
if(seperators.length >1 ){
regex = "" + seperators[0] + "|" + seperators[1];
}else{
regex = "" + seperators[0];
}
words = results.split(regex);
}
public String nextWord(){
if(pos == words.length)
return null;
return words[pos++];
}
}
3、编写一个程序,将d:\\java目录下的所有.java文件复制到d:\\jad目录下,并将原来文件的扩展名从.java改为.jad。
(大家正在做上面这道题,网上迟到的朋友也请做做这道题,找工作必须能编写这些简单问题的代码!)
答:listFiles方法接受一个FileFilter对象,这个FileFilter对象就是过虑的策略对象,不同的人提供不同的FileFilter实现,即提供了不同的过滤策略。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Jad2Java {
public static void main(String[] args) throws Exception {
File srcDir = new File("java");
if(!(srcDir.exists() && srcDir.isDirectory()))
throw new Exception("目录不存在");
File[] files = srcDir.listFiles(
new FilenameFilter(){
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
}
);
System.out.println(files.length);
File destDir = new File("jad");
if(!destDir.exists()) destDir.mkdir();
for(File f :files){
FileInputStream fis = new FileInputStream(f);
String destFileName = f.getName().replaceAll("\\\\.java$", ".jad");
FileOutputStream fos = new FileOutputStream(new File(destDir,destFileName));
copy(fis,fos);
fis.close();
fos.close();
}
}
private static void copy(InputStream ips,OutputStream ops) throws Exception{
int len = 0;
byte[] buf = new byte[1024];
while((len = ips.read(buf)) != -1){
ops.write(buf,0,len);
}
}
}
由本题总结的思想及策略模式的解析:
1.
class jad2java{
1. 得到某个目录下的所有的java文件集合
1.1 得到目录 File srcDir = new File("d:\\\\java");
1.2 得到目录下的所有java文件:File[] files = srcDir.listFiles(new MyFileFilter());
1.3 只想得到.java的文件: class MyFileFilter implememyts FileFilter{
public boolean accept(File pathname){
return pathname.getName().endsWith(".java")
}
}
2.将每个文件复制到另外一个目录,并改扩展名
2.1 得到目标目录,如果目标目录不存在,则创建之
2.2 根据源文件名得到目标文件名,注意要用正则表达式,注意.的转义。
2.3 根据表示目录的File和目标文件名的字符串,得到表示目标文件的File。
//要在硬盘中准确地创建出一个文件,需要知道文件名和文件的目录。
2.4 将源文件的流拷贝成目标文件流,拷贝方法独立成为一个方法,方法的参数采用抽象流的形式。
//方法接受的参数类型尽量面向父类,越抽象越好,这样适应面更宽广。
}
分析listFiles方法内部的策略模式实现原理
File[] listFiles(FileFilter filter){
File[] files = listFiles();
//Arraylist acceptedFilesList = new ArrayList();
File[] acceptedFiles = new File[files.length];
int pos = 0;
for(File file: files){
boolean accepted = filter.accept(file);
if(accepted){
//acceptedFilesList.add(file);
acceptedFiles[pos++] = file;
}
}
Arrays.copyOf(acceptedFiles,pos);
//return (File[])accpetedFilesList.toArray();
}
4、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉的半个”。
答:首先要了解中文字符有多种编码及各种编码的特征。
假设n为要截取的字节数。
public static void main(String[] args) throws Exception{
String str = "我a爱中华abc我爱传智def\';
String str = "我ABC汉";
int num = trimGBK(str.getBytes("GBK"),5);
System.out.println(str.substring(0,num) );
}
public static int trimGBK(byte[] buf,int n){
int num = 0;
boolean bChineseFirstHalf = false;
for(int i=0;i<n;i++)
{
if(buf[i]<0 && !bChineseFirstHalf){
bChineseFirstHalf = true;
}else{
num++;
bChineseFirstHalf = false;
}
}
return num;
}
5、有一个字符串,其中包含中文字符、英文字符和数字字符,请统计和打印出各个字符的个数。
答:哈哈,其实包含中文字符、英文字符、数字字符原来是出题者放的烟雾弹。
String content = “中国aadf的111萨bbb菲的zz萨菲”;
HashMap map = new HashMap();
for(int i=0;i<content.length;i++)
{
char c = content.charAt(i);
Integer num = map.get(c);
if(num == null)
num = 1;
else
num = num + 1;
map.put(c,num);
}
for(Map.EntrySet entry : map)
{
system.out.println(entry.getkey() + “:” + entry.getValue());
}
估计是当初面试的那个学员表述不清楚,问题很可能是:
如果一串字符如"aaaabbc中国1512"要分别统计英文字符的数量,中文字符的数量,和数字字符的数量,假设字符中没有中文字符、英文字符、数字字符之外的其他特殊字符。
int engishCount;
int chineseCount;
int digitCount;
for(int i=0;i<str.length;i++)
{
char ch = str.charAt(i);
if(ch>=’0’ && ch<=’9’)
{
digitCount++
}
else if((ch>=’a’ && ch<=’z’) || (ch>=’A’ && ch<=’Z’))
{
engishCount++;
}
else
{
chineseCount++;
}
}
System.out.println(……………);
6、说明生活中遇到的二叉树,用java实现二叉树
这是组合设计模式。
我有很多个(假设10万个)数据要保存起来,以后还需要从保存的这些数据中检索是否存在某个数据,(我想说出二叉树的好处,该怎么说呢?那就是说别人的缺点),假如存在数组中,那么,碰巧要找的数字位于99999那个地方,那查找的速度将很慢,因为要从第1个依次往后取,取出来后进行比较。平衡二叉树(构建平衡二叉树需要先排序,我们这里就不作考虑了)可以很好地解决这个问题,但二叉树的遍历(前序,中序,后序)效率要比数组低很多,原理如下图:
代码如下:
package com.huawei.interview;
public class Node {
public int value;
public Node left;
public Node right;
public void store(int value)
{
if(value<this.value)
{
if(left == null)
{
left = new Node();
left.value=value;
}
else
{
left.store(value);
}
}
else if(value>this.value)
{
if(right == null)
{
right = new Node();
right.value=value;
}
else
{
right.store(value);
}
}
}
public boolean find(int value)
{
System.out.println("happen " + this.value);
if(value == this.value)
{
return true;
}
else if(value>this.value)
{
if(right == null) return false;
return right.find(value);
}else
{
if(left == null) return false;
return left.find(value);
}
}
public void preList()
{
System.out.print(this.value + ",");
if(left!=null) left.preList();
if(right!=null) right.preList();
}
public void middleList()
{
if(left!=null) left.preList();
System.out.print(this.value + ",");
if(right!=null) right.preList();
}
public void afterList()
{
if(left!=null) left.preList();
if(right!=null) right.preList();
System.out.print(this.value + ",");
}
public static void main(String [] args)
{
int [] data = new int[20];
for(int i=0;i<data.length;i++)
{
data[i] = (int)(Math.random()*100) + 1;
System.out.print(data[i] + ",");
}
System.out.println();
Node root = new Node();
root.value = data[0];
for(int i=1;i<data.length;i++)
{
root.store(data[i]);
}
root.find(data[19]);
root.preList();
System.out.println();
root.middleList();
System.out.println();
root.afterList();
}
}
-----------------又一次临场写的代码---------------------------
import java.util.Arrays;
import java.util.Iterator;
public class Node {
private Node left;
private Node right;
private int value;
//private int num;
public Node(int value){
this.value = value;
}
public void add(int value){
if(value > this.value)
{
if(right != null)
right.add(value);
else
{
Node node = new Node(value);
right = node;
}
}
else{
if(left != null)
left.add(value);
else
{
Node node = new Node(value);
left = node;
}
}
}
public boolean find(int value){
if(value == this.value) return true;
else if(value > this.value){
if(right == null) return false;
else return right.find(value);
}else{
if(left == null) return false;
else return left.find(value);
}
}
public void display(){
System.out.println(value);
if(left != null) left.display();
if(right != null) right.display();
}
/*public Iterator iterator(){
}*/
public static void main(String[] args){
int[] values = new int[8];
for(int i=0;i<8;i++){
int num = (int)(Math.random() * 15);
//System.out.println(num);
//if(Arrays.binarySearch(values, num)<0)
if(!contains(values,num))
values[i] = num;
else
i--;
}
System.out.println(Arrays.toString(values));
Node root = new Node(values[0]);
for(int i=1;i<values.length;i++){
root.add(values[i]);
}
System.out.println(root.find(13));
root.display();
}
public static boolean contains(int [] arr, int value){
int i = 0;
for(;i<arr.length;i++){
if(arr[i] == value) return true;
}
return false;
}
}
7、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序:
1,张三,28
2,李四,35
3,张三,28
4,王五,35
5,张三,28
6,李四,35
7,赵六,28
8,田七,35
程序代码如下(答题要博得用人单位的喜欢,包名用该公司,面试前就提前查好该公司的网址,如果查不到,现场问也是可以的。还要加上实现思路的注释):
package com.huawei.interview;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;
public class GetNameTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//InputStream ips = GetNameTest.class.getResourceAsStream("/com/huawei/interview/info.txt");
//用上一行注释的代码和下一行的代码都可以,因为info.txt与GetNameTest类在同一包下面,所以,可以用下面的相对路径形式
Map results = new HashMap();
InputStream ips = GetNameTest.class.getResourceAsStream("info.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(ips));
String line = null;
try {
while((line=in.readLine())!=null)
以上是关于java用正则表达式判断一个18位身份证号是不是有效的主要内容,如果未能解决你的问题,请参考以下文章