正则表达式使用五例(转贴)

-、分组提取
以apache log为例,如下:

192.168.1.138 - - [03/Feb/2006:01:40:20 +0800] "GET /phpinfo.php HTTP/1.1" 404 295
//分别为 客户端IP、访问日期、请求路径、服务端响应Code、请求文件大小[@more@]-、分组提取
以apache log为例,如下:

192.168.1.138 - - [03/Feb/2006:01:40:20 +0800] "GET /phpinfo.php HTTP/1.1" 404 295
//分别为 客户端IP、访问日期、请求路径、服务端响应Code、请求文件大小

其正则表达式为:


String pattern=
"^([d.]+)(S+)(S+)[([w:/]+s[+|-]d{4})]s"(.+)"s(d{3})s(d+)";

想到上面正则中括号()的作用了么?可以通过group(i)快速的将每组()中内容提取出来。

第一组([d.]+):将IP地址匹配出来

第四组([w:/]+s[+|-]d{4}):将时间匹配出来

第五组(.+):将客户端请求内容匹配出来

第六组(d{3}):将服务端响应Code匹配出来

第七组(d+):将文件大小匹配出来

测试程序:

   import java.util.regex.*;
public class Test {
    public static void main(String[] args) {
     String pattern="^([d.]+)(S+)(S+)[([w:/]+s[+|-]d{4})]s"(.+)"s(d{3})s(d+)";

        String log="192.168.1.138--[03/Feb/2006:01:40:20 +0800] "Get /phpinfo.php HTTP/1.1" 404 295";
       
        System.out.println("pattern: " + pattern);
        System.out.println("log: " + log);
       
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(log);
       
        if (m.find()) {
            System.out.println("IP Address: " + m.group(1));
            System.out.println("Date&Time: " + m.group(4));
            System.out.println("Request: " + m.group(5));
            System.out.println("Response: " + m.group(6));
            System.out.println("Size: " + m.group(7));
        } else {
            System.out.println("error!");
        }
    }
 
}

 
  
    程序输出:
   
C:java>java   Test
pattern: ^([d.]+)(S+)(S+)[([w:/]+s[+|-]d{4})]s"(.+)"s(d{3})s(d+)
log: 192.168.1.138--[03/Feb/2006:01:40:20 +0800] "Get /phpinfo.php HTTP/1.1" 404  295
IP Address: 192.168.1.138
Date&Time: 03/Feb/2006:01:40:20 +0800
Request: Get /phpinfo.php HTTP/1.1
Response: 404
Size: 295


二、替换匹配的字符串

假如需要替换掉匹配正则表达式的字符串,我们可以自已使用String类的subString()方法,
但jdk1.4的正则表达式API中提供了实现此功能的相关方法,如下:

* replaceAll(newString); 替换全部符合正则表达式的子串为newString.

* appendReplacement(StringBuffer, newString); 将字符串中匹配正则的
    子串之前的字符串先传入到StringBuffer中,然后再加上newString。

* appendTail(StringBuffer); 将字符串中匹配最后一个正则表达式后面的
    字符串传入到StringBuffer(通常和appendReplacement一起使用).


看下面的例子:

   
import java.util.regex.*;
public class Test{  
 public static void main(String[] args) {

        // 匹配d开头,接着是a或e最少一次,最多2次,再接着是mon
        // 感觉自已跟唐僧一样,N啰嗦 -__-!!
       
        String pattern ="d[ae]{1,2}mon";
        String input ="Unix hath demons and deamons in it!";
        System.out.println("Input:" + input);
 
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(input);
        // 两个子串符合: demons, deamons.
        System.out.println("ReplaceAll:A=" + m.replaceAll("A"));
 
        m.reset();
 
        StringBuffer sb = new StringBuffer();
        System.out.println("Append methods:");
        
        while (m.find()) {
            m.appendReplacement(sb,"B");
            System.out.println(sb);
        }
       
        m.appendTail(sb);
        System.out.println(sb.toString()); 

   }
}

运行结果:

C:java>java   Test
Input:Unix hath demons and deamons in it!
ReplaceAll:A=Unix hath As and As in it!
Append methods:
Unix hath B
Unix hath Bs and B
Unix hath Bs and Bs in it!




三、查找

有时候你需要把字符串中匹配正则表达式的那一段找出来,接着前一个例子,
你可以调用“查找”方法成功后,调用下面的方法将匹配的字符串找出来。

start(), end()  返回字符串中匹配正则表达式的子串的开始位置和结束位置

groupCount()    返回()号匹配的数目,如果有的话。返回0表示没有使用()组,下面将会有介绍

group(int i)    返回正则表达式()匹配的第i组,如果i小于或等于groupCount()则返回相应的()匹配值,
                如果调用group(0)或group()则返回整个匹配正则表达式的部分

下面这个例子使用group()直接将整个匹配正则表达式的子字符串取出来:

import java.util.regex.*;
public class Test2{  
       
      public static void main(String[] args) {
        // 匹配Q开头,第二个字符不为u,后面接数字1次或多次,后面再.号
        String pattern ="Q[^u]d+.";
        Pattern p = Pattern.compile(pattern);
 
        String line ="Order QT300. Now !";
 
        Matcher m = p.matcher(line);
        if (m.find()) {
            // m.group()须调用相关查找方法成功后才能调用
            System.out.println(pattern + " matches "" + m.group() +"" in "" + line +""");
        } else {
            System.out.println("NO MATCH");
        }
    }
}


 
    // 输出:Q[^u]d+. matches "QT300." in "Order QT300. Now !" 
 
上面这个例子也可以使用start(), end()方法来完成:

import java.util.regex.*;
public class Test3{  
       
      public static void main(String[] args) {
        String pattern = "Q[^u]d+.";
        Pattern p = Pattern.compile(pattern);
 
        String line = "Order QT300. Now!";
        Matcher m = p.matcher(line);
 
        if (m.find()) {
            System.out.println(pattern + " matches ""
                    + line.substring(m.start(), m.end()) + "" in "" + line
                    + """);
        } else {
            System.out.println("NO MATCH!");
        }
    } 
}
  // 输出:Q[^u]d+. matches "QT300." in "Order QT300. Now !" 


四、转换
假设你想将字符串:
Smith, John
通过正则转换为:
John Smith
可以这样做:

import java.util.regex.*;
public class Test4{  
       
      public static void main(String[] args) {
       
        String line = "Smith, John";

        // 这就是上面所说的()号,如果调用groupCount()的话,将输出2
        // 匹配任何字符0次或多次,然后是","号和空格,再匹配任何字符0次和多次
        // 上面的任何字符不包括换行符
        Pattern p = Pattern.compile("(.*), (.*)");
 
        Matcher m = p.matcher(line);
        if (m.find()) {
            // 先取上面正则()中匹配的group 2,也就是John
            // 然后再取()中匹配的group 1,也就是Smith
            System.out.println(m.group(2) + " " + m.group(1));
        } else {
            System.out.println("NO MATCH!");
        }
    }
}

    // 输出: John Smith 


 
再看一个例子:交换两个参数的位置

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RearrangeText {
  public static void main(String args[]) {
    String regEx = "(Math.pow)"+                                  // Math.pow
    "s*(" +                                                   // Opening parenthesis
    "s*([+|-]?(d+.?d*|.d+)|([a-zA-Z]w*))" +         // First argument
    "s*,s*" +                                                 // Comma 
    "([+|-]?(d+.?d*|.d+)|([a-zA-Z]w*))" +             // Second argument
    "s*)";                                                    // Closing parenthesis

    String oldCode = "double result = Math.pow( 3.0, 16.0); " +
                "ndouble resultSquared = Math.pow(2 ,result );"+
                "ndouble hypotenuse = Math.sqrt(Math.pow(2.0, 30.0)+Math.pow(2 , 40.0));";
    Pattern pattern = Pattern.compile(regEx);
    Matcher m = pattern.matcher(oldCode);

    StringBuffer newCode = new StringBuffer();
    while(m.find()) {
      m.appendReplacement(newCode, "$1($5,$2)");//$1表示第一组,$i表示第i组
      //System.out.println("OK="+newCode);
   }
    m.appendTail(newCode);

    System.out.println("Original Code:n"+oldCode.toString());
    System.out.println("nNew Code:n"+newCode.toString());
  }
}

运行结果:

C:java>java   RearrangeText
Original Code:
double result = Math.pow( 3.0, 16.0);
double resultSquared = Math.pow(2 ,result );
double hypotenuse = Math.sqrt(Math.pow(2.0, 30.0)+Math.pow(2 , 40.0));

New Code:
double result = Math.pow(16.0,3.0);
double resultSquared = Math.pow(result,2);
double hypotenuse = Math.sqrt(Math.pow(30.0,2.0)+Math.pow(40.0,2));



五、匹配

在java中我们可以简单的使用String类的matches()方法来判断当前字符串是否符合
你所给定的正则表达式模式。matches()方法接受正则表达式做为参数,返回boolean类型。

if (inputString.matches(regexPattern)) {
    // 字符串inputString匹配regexPattern这个模式
} 
代码很简单,但是效率不高,如果在程序中使用不止一次,我们可以使用Pattern和Matcher,例子见下:

   import java.util.regex.*;
public class Test5{  
       
      public static void main(String[] args) throws PatternSyntaxException {
        String pattern = "^Q[^u]d+.";
        String input = "Qa777. is the next flight. It is on time.";
 
        Pattern p = Pattern.compile(pattern);
        boolean found = p.matcher(input).lookingAt();
 
        System.out.println("'" + pattern + "'"
                + (found ? " matches '" : " doesn't match '") + input + "'");
    } 
}

运行结果

C:java>java   Test5
'^Q[^u]d+.' matches 'Qa777. is the next flight. It is on time.'

六、小结:
在程序中使用正则表达式的步骤一般如下:
1. 建立Pattern对象,通过静态方法Pattern.compile();
2. 取得Matcher对象,通过pattern.matcher(CharSequence charSequence);
3. 调用Matcher对象的相关查找方法。

java.lang.CharSequence接口是在JDK1.4版本中被添加进来的,它为不同种类的char序列
提供了统一的只读访问。实现的类有String, StringBuffer, java.nio.CharBuffer

Matcher提供几个不同的查找方法,比String类的matches()方法更灵活,如下:

match() 使用整个字符串与相关模式相比较,和String的matches()差不多

lookingAt() 从字符串开头的地方与相关模式比较

find() 匹配字符串,没有必要从字符串的第一个字符开始,如果前一个操作匹配,
而且匹配器没有重置的话,则从不匹配的第一个字符开始。

上面每个方法都返回boolean类型,返回true则意味的匹配,返回false则不匹配。

要检测给定的String是否匹配给定的模式,只须下面这样就可以了:

Matcher m = Pattern.compile(yourPattern).matcher(yourString);
 
if (m.find()) {
    System.out.println(“match”);
} else {
    System.out.println(“no match”);
} 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/802415/viewspace-837046/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/802415/viewspace-837046/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值