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 Homework 
public 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位身份证号是不是有效的主要内容,如果未能解决你的问题,请参考以下文章

验证身份证号码的正确正则表达式

Java-18位身份证号的正则表达式。帮忙拆一下代码。

使用java判断输入身份证号位数是不是正确,判断输入是不是有效

JS验证身份证的正则表达式?

Java笔试题之《算法与编程》

正则表达式 - 15位 & 18位身份证号