博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

14、正则表达式

Posted on 2013-08-15 13:43  mz_zyh  阅读(342)  评论(0编辑  收藏  举报

正则表达式

正则表达式:符合一定规则的表达式

  作用:用于专门操作字符串的。

 

  特点:用一些特定的符号来表示一些代码操作,这样就简化了书写。

       所以学习正则表达式就是在学习一些特殊符号的使用。

 

  好处:可以简化对字符串的复杂操作

  弊端:符合定义越多,正则越长,阅读性越差。

 

  具体操作功能:

    1、匹配:

      String matches(String regex)方法,用规则匹配整个字符串,只要又一次不符合规则,就匹配结束,返回false 

代码实例:

/**

 * 该方法采用正则表达式的方式对QQ号码进行校验

 */

public static boolean checkQQRegex(String qq){

  String regex = "[1-9]\\d{4,14}";

  boolean flag = qq.matches(regex);

  if(flag){

    System.out.println(qq);

  } else {

    System.out.println("QQ号码输入错误");

  }

  return !flag;

}

  

    2、切割:

      String split(String regex);

        注意切割标识:.和\\

          .表示任意字符,要使用.作为切割标准,表现转义\\.

          用\\切割时,表示为\\\\

String str = "zhangsan.lishi.wangwu";

String regex = "\\.";

String[] arr = str.split(regex);

for(String s : arr){

  System.out.println(s);

}

 

String str = "c:\\abc\\test.java";

String regex = "\\\\";

String[] arr = str.split(regex);

for(String s : arr){

  System.out.println(s);

}

  

  组的概念:

    当需要重复使用同一个规则时,可以将其封装成组,组会自动编号,调用组只需要用\加组号

 

    按照叠词完成切割,为了可以让规则的结果可以被重用,可以将规则封装成一个组,用小括号完成(),组的出现都有编号,从1开始,想要使用已有的组,可以使用\n的形式来获取,n为组的编号

    ((())())一共有四个组,看组必须看左括号,有几个左括号就有几个组,并且,组号也是按照左括号排的

String str = "ajddflkasssdsjgljqqqqasg";

String regex = "(.)\\1+";

String[] arr = str.split(regex);

for(String s : arr){

  System.out.println(s);

}

  

    3、替换:

      String replaceAll(String regex,String replacement);特例:特殊符合$,可以用$获取其他正则表达式中的组

 

public static void main(String[] args) {

  String str = "iogjsd234235ddajnf1234glkas432jlss54323456skjo";

  String regex = "\\d";
  
  String newstr = "#";

  replaceAll(str,regex,newstr);

}

 

/**

 * 该方法的用于使用正则表达式对字符串进行替换处理

 */

public static void replaceAll(String str,String regex,String newstr){

  str = str.replaceAll(regex,newstr);

  System.out.println(str);

}

  

    4、获取:将字符串中符合规则的子串取出。

      操作步骤:

        a) 将正则表达式封装成对象

        b) 让正则对象和要操作的字符串相关联

        c) 关联后,获取正则匹配引擎

        d) 通过引擎对符合规则的子串进行操作,比如取出

 

Pattern类

  正则表达式的编译表示形式。

  该类没有构造函数,对外提供了一个静态方法compile(String regex);将给定的正则表达式编译到模式中,即会返回一个Pattern对象 

  用compile方法可以将正则表达式封装成对象

 

  该类中方法matcher(CharSequence input);可以将Pattern对象和所要操作的字符串相关联。

  该方法会返回一个新的匹配器Matcher对象

 

类Matcher

  通过解释Pattern对charactersequence执行匹配操作的引擎

  其实String类中的matches方法,用的就是Pattern和Matcher对象来完成的,只不过被String的方法的封装后,用起来较为简单,但是功能却单一。

  该类中方法group()能够获得匹配操作所匹配的输入子序列。

    如果没有尝试任何匹配,或者以前的匹配操作失败,会抛出IllegalStateException异常。

    即要先匹配后才进行获取。

 

  类中方法find(),可以尝试查找与该模式匹配的输入序列的下一个子序列。

    此方法从匹配器区域的开头开始,如果该方法的前一次调用成功了并且从那时开始匹配器没有被重置,则从以前匹配操作没有匹配的第一个字符开始。

    如果匹配成功,则可以通过start、end和group方法获取更多信息。

    当且仅当输入序列的子序列匹配此匹配器的模式时才返回true。

 

  正则的取出,类似以迭代器的方式,必须先判断,然后再取出,判断用find,取出用group

  该类中还可以获取匹配的字符串的位置,通过start和end来获得

  Start获取该匹配的子串的初始位置,end获得该匹配子串的结束位置

代码示例:

public static void main(String[] args) {

  String str = "jin tian wo hen gao xing.yin wei wo gan jue zi ji you zhao dao le fen dou de ji qing.";

  String regex = "\\b[a-z]{4}\\b";

  getString(str,regex);

}

 

/**

 * 该方法用于通过正则表达式的方式获取匹配的字符串

 */

public static void getString(String str,String regex){

  //1、将正则表达式封装成对象

  Pattern pat = Pattern.compile(regex);
 

  //2、将正则表达式对象与所要操作的字符串想关联,获得匹配器

  Matcher mat = pat.matcher(str);
 

  //3、通过匹配器进行匹配,并获得匹配的字符串,打印在控制台

  while(mat.find()){

    System.out.println(mat.group());
    
    System.out.println(mat.start()+"....."+mat.end());
  
  }

}

 

 

  在用正则表达式解决字符串问题时,到底用四种功能中的哪一个呢,或者哪几个呢?

  思考方式:

    1、如果只想知道该字符是否对错,使用匹配

    2、想要将已有的字符串变成另一个字符串,可以替换

    3、想要按照指定的方式将字符串变成多个字符串,可以使用切割,切割其实就是获取规则以为的子串。

    4、想要拿到符合需求的字符串子串,可以获取。其实是获取符合规则的子串。

 

练习:

 1 采用正则表达式的方式,将字符串

   * "我我...我我...我要..要要..要要..学学学...学学...编编编...编程.程..程程...程...程"

   * 转成"我要学编程"

public static void main(String[] args) {

  String str = "我我...我我...我要..要要..要要..学学学...学学...编编编...编程.程..程程...程...程";

  System.out.println(regexTest_1(regexTest_1(str, "\\.+",""), "(.)\\1+","$1"));

}
 

/**

 * 该方法用于将字符串按照给定的规则进行处理

 */

public static String regexTest_1(String str,String regex,String newstr){

  return str.replaceAll(regex, newstr);

}

 

 

   * 练习2:

     * 需求:将下列ip地址进行地址段顺序的排序

     * 192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30

public static void main(String[] args) {

  String str = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30 2.2.3.2 2.2.2.4";

// sort_1(str);

  sort_2(str);
  
}

 

/**

 * 该方法采用字符串自身具备的比较性进行ip地址段顺序排序

 */

public static void sort_2(String str){

  //1、将ip地址段前面都补零,保证最小字段都能补足为3位

  str = str.replaceAll("(\\d+)", "00$1");

 

  //2、将ip地址段中超过3位的多余的0清除,保证每个地址段都为3位

  str = str.replaceAll("0*(\\d{3})", "$1");

 

  Set<String> set = new TreeSet<String>();

 

  //3、按" "切割出每个ip地址,并存入Set中,按照字符串自身比较性排序

  for(String s : str.split(" ")){

    set.add(s);

  }

 

  for(String s : set){

    //4、将排好序的ip地址中多余的0去除后打印

    System.out.println(s.replaceAll("0*(\\d)", "$1"));

  }

}

 

/**

 * 该方法用于将传入的ip地址字符串进行按地址段顺序排序

 * 思路:

 *   1、先将传入的字符串按" "切割,将得到的字符串数组中的元素存入set集合中

 *   2、对set集合创建比较器,按地址段进行排序

 *   3、打印排好序的ip地址

 */

public static void sort_1(String str){

  //1、将传入的ip地址字符串切割出独立的ip地址

  String[] ips = str.split(" +");

 

  //2、定义Set集合,存储ip地址,并定义比较器进行比较排序

  Set<String> set = new TreeSet<String>(new Comparator<String>(){

    public int compare(String s1,String s2){

      String[] ss1 = s1.split("\\.");

      String[] ss2 = s2.split("\\.");

      int temp = 0;

 

      for(int x=0;x<4;x++){

        temp = Integer.parseInt(ss1[x])-Integer.parseInt(ss2[x]);

        if(temp!=0)

          break;

      }

      return temp;

    }

  });

 

  for(String ip : ips){

    set.add(ip);

  }

 

  for(String ip : set){

    System.out.println(ip);

  }

}

 

 

网页爬虫练习,其实质就是获取网页上的数据,在根据正则表达式方法获取符合要求的字符串

在通过正则获取时,必须注意正则获取的步骤:

  1、将正则表达式封装成对象

  2、通过Pattern对象关联要处理的数据,并获取匹配器引擎

  3、通过Matcher对象,通过对象中方法find判断是否还存在符合要求的数据,通过group方法获取符合要求的数据

  4、注意:必须先判断是否存在符合要求的数据后才可以进行获取,若不然或抛出异常。