zoukankan      html  css  js  c++  java
  • Scanner几个问题与正则简介

      Pre:最近做了头条的在线笔试,对Scanner输入的处理有些特殊,当时是一脸懵逼态,遂由此随笔(/@_@),java小白,有错难免!

      查了下Scanner的源码,没有头绪,但是其中用到了正则的知识,遂简单回顾下正则的使用:

    Part1:正则使用简介                    

      1、正则表达式主要是针对字符串的一种规则(以字符串表示);主要功能有以下:

    • 匹配:注意是完全匹配, boolean matches(String regex)  (我之前总是一不小心就理解成包含contains)。
    • 切割:返回是字符串组,  String[] split(String regex)
    • 替换:多种替换方法如: String replace(char oldChar, char newChar)
    • 获取:需要Pattern类和Matcher类支持,
      • Pattern类:模式,字符串形式的正则首先被编译为此类的实例
        • static Pattern compile(String regex)//获取模式 
        • Matcher matcher(CharSequence input)//获取匹配器 
      • Matcher类:匹配器,解释Pattern并执行匹配操作。
        • boolean find()  //是否有下一个可匹配的子序列 
        • String group()   //返回匹配的子序列
        • int end()        //返回最后一个匹配位置的下一个位置

      2、java实例:

    public class Test {
        public static void main(String[] args) {
            String reg="abc";
            String str="abcdefabcdefababc";
            Pattern p=Pattern.compile(reg);
            Matcher m=p.matcher(str);
            while(m.find()){
                System.out.println(m.group()+"起始于:"+m.start()+",结束于:"+(m.end()-1));
            }
        }
    }
    abc起始于:0,结束于:2
    abc起始于:6,结束于:8
    abc起始于:14,结束于:16
    View Code

      3、常用的正则规则:具体可转:https://www.cnblogs.com/Jansens520/p/6915384.html

    {}:表示次数 ; [a,b,c]{3,}:a,b,c中的一个出现至少3次  
    []:表示一个集合,可以是其中的任何一个字符;
    
    预定义字符
    . :任何字符;              
    d:数字0-9;            D:非数字0-9即[^0-9];
    w:单词字符[a-zA-Z_0-9];    W:非单词开头
    s:任何空白字符[<空格>	
    
    fv];如"asc"可匹配"a c";   
    S: 非空白字符[^s]
    
    边界匹配:
    ^:行的开头           $:行的结尾
    A:仅匹配字符串开头       :仅匹配字符串结尾  "Aabc",“abc”匹配“abc”;
    :单词边界 "a!c"匹配“a!c”;B:非单词边界
    数量:
    x?:x出现一次或一次也没有
    x*:x出现0次或多次
    x+:x出现1次或多次 
    
    组:
    ():表示组,每遇到“(”编号+1;
    a(123|bcd){2}e:匹配“a123123e”不匹配"a123bcde",组要么是123,要么是bcd;
    View Code

     Part2:使用Scanner输入碰到的几个问题                   

      1、几个方法:

    • String next():从第一个有效字符(非空格、换行等)直到第一个分隔或结束符(空格或换行) 
    • int nextInt():读取一个int类型 
    • String nextLine():从当前开始直到行分隔符; 

      2、nextInt与nextLine同时使用问题:

      问题:第一行输入m与n,以空格分开;然后连续m行;空行;连续n行?

    public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int m=sc.nextInt();
            int n=sc.nextInt();
          //sc.nextLine();//正确输入时添加该行,we3前加空行;
            String[] str1=new String[m];
            String[] str2=new String[n];
            for(int i=0;i<m;i++){
                str1[i]=sc.nextLine();
            }
            sc.nextLine();//跳过一行;
            for(int i=0;i<n;i++){
                str2[i]=sc.nextLine();
            }
            System.out.println(m+";"+n);
            System.out.println(Arrays.toString(str1));
            System.out.println(Arrays.toString(str2));
    }
    分析:这里跳过了一行,第一行nextInt读到2后,定位到换行符之前,nextLine()读取到换行符,所以是"",而不是we1;
    因此想要正确改正:
    输入:
    2 2
    we1
    we2
    we3
    we4
    
     输出:
    
    2;2
    [, we1]
    [we3, we4]
    nextInt与nextLine同时使用

        3、比较问题(字符串的==与equals问题):

     

      

      

     

      切记:要用equals不要用“==”;后者比较地址,两个""的地址不相同。

    public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int m=sc.nextInt();
            String[] str1=new String[m];
            sc.nextLine();
            for(int i=0;i<m;i++){
                str1[i]=sc.nextLine();
            }
            System.out.println(Arrays.toString(str1));
            for(int i=0;i<m;i++){
                if(str1[i]==("")){//
                    System.out.println("==检测到有空行");
                }
                if(str1[i].equals("")){
                    System.out.println("equals检测到有空行");
                }
            }
        }
    输入:
    2
    
    s
    输出
    [, s]
    equals检测到有空行;
    View Code

      为什么String不用"==",这是因为虽然值是一样的,但是量个""的地址不同;如下

     

            public static void main(String[] args) {
            String str1=new String("");
            String str2="";
    //打印内存地址;
            System.out.println(System.identityHashCode(str1));
            System.out.println(System.identityHashCode(str1));
            get();
        }
        private static void get(){
            System.out.println(System.identityHashCode(""));
        }
    
    输出:
    17225372
    17225372
    5433634

      

     

      

     

    4、笔试时碰到过这样一个问题:

     

      

     

      题目没有说明Scanner输入的大小,也就是我们不知道会有多少个nextLine(),nextInt;我当时想用3中的方法:当检测到一个空行时,停止等待输入,执行后续代码:如下;

     

     

    public static void main(String[] args) {
                Scanner sc=new Scanner(System.in);
                ArrayList<String> list=new ArrayList<>();
                boolean t=true;
                while(t){
    //                if(sc.hasNext())     该行必须要注释掉,否则即使输入空行,hashNext检测不到下一个输入标记而一直阻塞;
                        list.add(sc.nextLine());
                    if(list.get(list.size()-1).equals("")){
                        t=false;
                        list.remove(list.size()-1);
                    }
                }
                for(String s:list){
                    System.out.println(s);
                }
                System.out.println("有没有空行输出?");
                
        }
    粘贴输入:
    asdasda
    asdas
    
    asdasda
    输出:
    asdasda
    asdas
    有没有空行输出?
    未规定输入行数的处理

     

    以上是再做笔试时遇见的几个问题,后续碰到问题继续补充!  

  • 相关阅读:
    Spring 注解详解01
    java 排序算法
    Java 文件拼接器
    oracle join
    Oracle 去重
    Java 笔试面试
    Oracle 笔试题02
    jvm性能查看常用命令
    关于对JMM(java内存模型)的个人理解
    RSA前端加密后端解密避免出现明文密码
  • 原文地址:https://www.cnblogs.com/whtblog/p/9029208.html
Copyright © 2011-2022 走看看