正则表达式——实例分析

(1)应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
String.prototype.len=function(){return this.replace([^x00-xff]/g,”aa”).length;}
----------------------------------------------------------------------------------------------------------


(2)应用:javascript中没有像vbscript那样的trim函数,我们就可以利用这个表达式来实现
String.prototype.trim = function()
{
return this.replace(/(^s*)|(s*$)/g, “”);
}
----------------------------------------------------------------------------------------------------------


(3)应用:利用正则表达式分解和转换IP地址
function IP2V(ip) //IP地址转换成对应数值
{
re=/(d+).(d+).(d+).(d+)/g //匹配IP地址的正则表达式
if(re.test(ip))
{
return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1
}
else
{
throw new Error(”Not a valid IP address!”)
}
}

不过上面的程序如果不用正则表达式,而直接用split函数来分解可能更简单,程序如下:
var ip="10.100.20.168"
ip=ip.split(".")
alert("IP值是:"+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))
----------------------------------------------------------------------------------------------------------


(4)应用:从URL地址中提取文件名的javascript程序,如下结果为page1
s=”http://www.9499.net/page1.htm”;
s=s.replace(/(.*/){0,}([^.]+).*/ig,”$2″) ; //Page1.htm
----------------------------------------------------------------------------------------------------------


(5)应用:利用正则表达式限制网页表单里的文本框输入内容
用正则表达式限制只能输入中文:οnkeyup=”value=”/blog/value.replace(/[”^u4E00-u9FA5]/g,”) ” onbeforepaste=”clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^u4E00-u9FA5]/g,”))”
用正则表达式限制只能输入全角字符: οnkeyup=”value=”/blog/value.replace(/[”^uFF00-uFFFF]/g,”) ” onbeforepaste=”clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^uFF00-uFFFF]/g,”))”
用正则表达式限制只能输入数字:οnkeyup=”value=”/blog/value.replace(/[”^d]/g,”) “onbeforepaste= “clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^d]/g,”))”
用正则表达式限制只能输入数字和英文:οnkeyup=”value=”/blog/value.replace(/[W]/g,””) “onbeforepaste=”clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^d]/g,”
----------------------------------------------------------------------------------------------------------


(6)利用正则表达式去除字串中重复的字符的算法程序:
var s="abacabefgeeii"
var s1=s.replace(/(.).*1/g,"$1")
var re=new RegExp("["+s1+"]","g")
var s2=s.replace(re,"")
alert(s1+s2) //结果为:abcefgi
----------------------------------------------------------------------------------------------------------


(7)在字符串中精确查找链接地址
((http|https|ftp):(\/\/|\\\\)((\w)+[.]){1,}(net|com|cn|org|cc|tv|[0-9]{1,3})(((\/[\~]*|\\[\~]*)
(\w)+)|[.](\w)+)*(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)

我们知道,链接地址一般以http或者https或者ftp等形式出现。初步总结一下就是,链接地址必须符合如下条件:
条件1
 以http://或者https://或者ftp://等开头(当然还有其它形式,这里只列出主要的)
条件2
 http://后面必须跟一个单词字符,紧接着单词字符后面的是"."(这样的组合必须出现一次或多次)。紧跟着“.”后面的是域名后缀(如net或者com或者cn等,如果是以IP地址的形式出现就可以是数字)
条件3
 出现完整的链接地址后,还可以出现下一级或者更多级的目录(还要注意个人主页的地址有可能出现"~"符号)
条件4
 链接地址末尾可以带参数。如典型的页数?PageNo=2&action=display等
现在我们用下面的代码来逐个匹配上面的条件——


1、((http|https|ftp):(\/\/|\\\\) 满足条件1
表示http:// http:\\ https:// https:\\ ftp:// ftp:\\都匹配(在这里考虑了某些用户可能把"//"输成“\\”的易发性错误)
注意:"|"表示“或者”,"\"是转义字符。“\/\/”表示"//",“\\\\”表示"\\"

2、((\w)+[.]){1,}(net|com|cn|org|cc|tv|[0-9]{1,3}) 满足条件2
“((\w)+[.]){1,}”表示一个单词字符加一个点号可以出现1次或者多次(这里考虑了某些用户喜欢省略www而将http://www.w3c.com写成http://w3c.com)
“(net|com|cn|org|cc|tv|[0-9]{1,3})”表示必须要以net或者com或者cn或者org或者cc或者tv或者三位以下的数字结束
[0-9]{1,3}表示三位以下的数字,因为ip地址的任何段不能超过255

3、(((\/[\~]*|\\[\~]*)(\w)+)|[.](\w)+)* 满足条件3
“(\/[\~]*|\\[\~]*)”表示可以出现"/~"或者是"\~",(其中“[\~]*”表示 ~ 可以出现也可以不出现),因为不是每个链接地址都有下一级目录
“(\w)+)|[.](\w)+)”表示必须出现一个单词字符(即目录或者是一个带有扩展名的文件)
注意:最后还有一个“*”表示上面括号内的可以出现也可以不出现,否则就只能匹配有下一级目录的链接地址了。

4、(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)满足条件4
“((([?](\w)+){1}[=]*))*((\w)+){1}”表示形如"?PageNo=2"的字符串可以出现也可以不出现,如果出现则只能出现一次(因为不可能有两个“?”号出现)。

“([\&](\w)+[\=](\w)+)*)”表示形如“&action=display”的字符串可以出现也可以不出现(因为并不是每个网页都带有两个以上的参数。

整个“((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*”表示形如“? PageNo=2&action=display”的字符串可以出现也可以不出现(即链接地址可以有参数也可以没有参数)

把上面的组合起来,我们就可以匹配一个比较全面的链接地址了。比用简单的“(http:\/\/\S+)”来匹配一个链接地址要好,读者可以自行行测试比较。当然,这段代码还有很多不足之处,希望大家能够继续改进。
----------------------------------------------------------------------------------------------------------


(8)替代典型的标签:[/b]
我们的目的就是要把[b]成对的替换成<b></b>下面来看我们实现它的模板
  (\[b\])(.+)(\[\/b\])
这里用了"(.+)"来配匹到之间的整个字符串,在替代的时候我们要写成这样
  str=checkexp(re,str,"<b>$2</b>")
(注意:checkexp是我自定义的函数,将在后面给出。这个函数将把[/b]按照我们提供的模板进行替代。)

也许你会问这里出现一个"$2"是什么东东,呵注意了这个$2可是很重要的,它代表了"(.+)"所配匹的整个字符串。
为什么是$2而不是$1、$3呢?因为$1代表(\[b\])所匹配的"[b]"字符串,$3代表(\[\/b\])所匹配的""字符串,显然这里我们需要的是$2而不是$1$3。
----------------------------------------------------------------------------------------------------------


(9)<div class="a">北京</div> <div class="b">上海</div>怎么得到上海
结果:"<div\\s+class=\"b\"\\s*>(.+?)</div>" 
----------------------------------------------------------------------------------------------------------


(10)如何用正则表达式判断(第3和第3fsdf)这两种形式为非法,其余组合为合法,前提条件是能输入的只有数字,字母,中文。
var value = "第3fsdf";  
var pattern = /^第3(fsdf)?$/;  
if(value.match(pattern)){  
    alert(非法);  

----------------------------------------------------------------------------------------------------------


(11)匹配一个英文姓名的js 正则表达式
例如: li/ming   mi ng/li  m i ng /  l i 
姓和名之间一定得用特殊符号"/"来隔开,姓和名同时可以有多个空格
除了特殊符号"/"以外,任何特殊等号都不可以出现。

/^([a-z\s]+)\/([a-z\s]+)$/i 
----------------------------------------------------------------------------------------------------------


(12)<a href="11">11</a><a href="22">22</a>
用正则表达式如何找到第一个<a到第一个</a>之间的内容?

"<a href=\"11\">11</a><a href=\"22\">22</a>".replaceAll("(?i)<a(.*?)>[^<]+</a>","$1")
结果是href="11" href="22"

用“<a.*</a>”只能匹配到最后那个</a>,而没有匹配到第一个</a>的
<a.*</a>
改成
<a.*?</a>
默认情况下为贪婪模式,也就是最大匹配,<a.*</a>会匹配它能找到的最长的字符串,加上?就是懒惰模式,会找到最短的字符串

----------------------------------------------------------------------------------------------------------


(13)要实现下面的功能;
String s="1-4级份开始到福建卡的师傅2-8级份开始到5福建卡的师傅9-14级份开始到福建卡的师傅$";

提取1-4级,2-8级等等这样的字段,放在一个数组中
eg;string[] ss=.....;
    ss[0]=1-4级;  ss[1]=2-8级; ......
用Java语言写,最好用Java自带的正则表达式库;

import java.util.ArrayList;  
import java.util.List;  
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  
class StringTest{  
        public static void main(String[] args){  
           new StringTest().testRegex();  
        }  
    public void testRegex(){  
        String str="1-4级份开始到福建卡的师傅2-8级份开始到5福建卡的师傅9-14级份开始到福建卡的师傅$";  
        String reg = "(\\d+-\\d+级)";  
        String[] marches = this.findMarch(str, reg);  
                System.out.println("Find:"+marches.length);  
    }  
      
    private String[] findMarch(String str,String reg){  
        Pattern pattern = Pattern.compile(reg);  
        Matcher matcher = pattern.matcher(str);  
        List<String> list = new ArrayList<String>();  
        while(matcher.find()){  
            System.out.println(matcher.group(1));  
            list.add(matcher.group(1));  
        }  
        String[] marches = new String[list.size()];  
        for(int i=0; i<list.size(); i++){  
            marches[i] = list.get(i);  
        }  
        return marches;  
    }  

----------------------------------------------------------------------------------------------------------


(14)某个非数字字符串后面只跟3个数字
js: /^[^0-9]{1,}[0-9]{3}$/   

[^0-9]{1,} 匹配非数字,出现一次以上.
[0-9]{3} 匹配出现三次的数字

java:Pattern p = Pattern.compile("[^0-9]{1,}[0-9]{3}");

----------------------------------------------------------------------------------------------------------


(15)判断字符是否是除了 @  ——  , ? “” |  ~  %  *  !之外的其他符号?
import java.util.regex.Pattern;  
import java.util.regex.Matcher;  
public class testMatch2{  
    public static boolean checkNameReg(String str) {     
       String badword = "[^@——,?“”|~%*!]";     
       Pattern pattern = Pattern.compile(badword);     
       Matcher matcher = pattern.matcher(str);     
       return matcher.find();     
    }    
 
    public static void main(String[] args){  
        String str = "@——";  
        System.out.println("str match result:"+checkNameReg(str));  
          
        String str2 = "开始";  
        System.out.println("str match result:"+checkNameReg(str2));  
          
    }  

----------------------------------------------------------------------------------------------------------


(16)匹配除078之外的三位数

\\d{3}(?<!078)
----------------------------------------------------------------------------------------------------------


(17)var s = "ab
cd
ef
gh";
现在想把s里面的回车换行转换成$符号。。。。

s.replace(/\n/mg, '$')  或者  s.replace(/\n/g, '$') 

----------------------------------------------------------------------------------------------------------


(18)在JS中,求一正则表达式用以识别以下表达式是否合法: 
 A > B      A < B     A >= B     A <= B    A != B
其中 A B 为不是 <,>,= 的任何字符串,而且A B必存在  <,>,>=,<=,!= 两边可以用0到n个空格
如   fddd > fda3  fdafds != dddd   fda <= fdsa   合法
     fddd ! fda   fdsafdsa >=      fdee !=       不合法

"其中 A B 为不是 <,>,= 的任何字符串"
如果是这样的话,就是[^<>=]+\s*(([<>!]{0,1}=)|[<>=]{1,1})\s*[^<>=]+
如果带!,就是 [^<>!=]+\s*(([<>!]{0,1}=)|[<>=]{1,1})\s*[^<>!=]+
A!=(空格)  被实别为 true    修改为 [^<>=\s]+\s*(([<>!]{0,1}=)|[<>=]{1,1})\s*[^<>=\s]+  可以

----------------------------------------------------------------------------------------------------------


(19)判断一个字符串是不是以“yyyy-mm-dd”的格式输入的

String patternStr = "^((((19){1}|(20){1})(\\d){2})|(\\d){2})[-\\s]{1}[01]{1}(\\d){1}[-\\s]{1}[0-3]{1}(\\d){1}$";
----------------------------------------------------------------------------------------------------------


(20)String table = "<table>sdafaf<tr></tr>dasdf</table>sadfadfasdf</table>sadfasdfasdfadsf</table>";
假如现在有这么一个字符串。
想截取第一个<table></table>中的内容

Pattern pattern = Pattern.compile("<table>((?!</table>).)*</table>");
----------------------------------------------------------------------------------------------------------


(21)问题描述:
resultStr = "@inproceedings{1031197, author = {S. Alireza Aghili and Divyakant Agrawal and Amr El Abbadi}, title = {Protein structure alignment using geometrical features}, booktitle = {CIKM '04: Proceedings of the thirteenth ACM international conference on Information and knowledge management}, year = {2004}, isbn = {1-58113-874-1}, pages = {148--149}, location = {Washington, D.C., USA}, doi = {http://doi.acm.org/10.1145/1031171.1031197}, publisher = {ACM}, address = {New York, NY, USA}, },"

要将resultStr中{}内部的内容识别出来,并与 = 前的内容匹配。即得到
author的值为S. Alireza Aghili and Divyakant Agrawal and Amr El Abbadi,
title的值为Protein structure alignment using geometrical features,等等。

rs:
String resultStr ="字符串";     
Pattern p = Pattern.compile("[\\s\\t]+([\\w\\s]+)=[\\s]+\\{([^}]+)\\}");        
    
Map tmpMap = new HashMap();     
Matcher m = p.matcher(resultStr);        
while(m.find()){        
    String key=m.group(1);     
    String value=m.group(2);         
    System.out.println(key+"="+value);        
    tmpMap.put(key,value);     
}       
GlobalMode obj = new GlobalMode();      
obj.setAuthor(tmpMap.get("author"));     
obj.setTitle(tmpMap.get("title"));     
....  
----------------------------------------------------------------------------------------------------------


(22)"**jsunit/**/*.js" 这个类型的正则表达式用JAVA怎么去写.

".*jsunit\\/.*\\/.*\\.js" 
----------------------------------------------------------------------------------------------------------


(23)一个奇怪的正则问题
System.out.println("111".matches("(\\d)((?!\\1)\\d)\\3"));  
输出false 
System.out.println("111".matches("((\\d)((?!\\1)\\d)\\3)"));  
怎么会是true 

因为前一个正则表达式里,匹配到(?!\1)的时候,第一个捕获分组((\d))已经匹配到内容了,内容是1,而这里的否定正向环视要求这个位置的右边不是1,所以不匹配。
后一个正则表达式里,匹配到(?!\1)的时候,第一个捕获分组尚未匹配完因而内容还是空的,这样这个否定正向环视就不影响后续匹配,最后整个正则表达式就匹配了。
----------------------------------------------------------------------------------------------------------


(24)用正则表达式去检查mail地址时,而mail地址比较怪,用了"-",而"-"恰好是正则里的特殊字符,用\\-去过滤,不成功,给个思路?

public class RegexTest extends TestCase {  
 
    public void test() {  
        String regex = "[a-zA-Z\\-]";  
          
        assertTrue(Pattern.compile(regex).matcher("a").matches());  
        assertTrue(Pattern.compile(regex).matcher("A").matches());  
        assertTrue(Pattern.compile(regex).matcher("-").matches());  
 
        assertFalse(Pattern.compile(regex).matcher("1").matches());  
        assertFalse(Pattern.compile(regex).matcher(".").matches());  
        assertFalse(Pattern.compile(regex).matcher(">").matches());  
    }  

----------------------------------------------------------------------------------------------------------


(25)如何匹配 任意连续字符
比如  123aa4556 中的aa ,55

import java.util.regex.*;  
 
public class Test {  
    public static void main(String[] args) {  
        Pattern p = Pattern.compile("(.)\\1+");  
        String str = "12333455aaabc677";  
        Matcher m = p.matcher(str);  
        while (m.find()) {  
            System.out.println(str.substring(m.start(), m.end()));  
        }  
    }  
}  
 
// 输出:  
// 333  
// 55  
// aaa  
// 77 

----------------------------------------------------------------------------------------------------------


(26)用正则表达式匹配一个insert的SQL语句,能够自动地将变量赋给对应的字段,比如
SQL=“insert into table(item1,item2,item3) values(:item1,:item2,:item3)”
map.put(item1,"111")
map.put(item2,"222")
map.put(item3,"333")

想用正则表达式自动的将SQL语句中的:item1,:item2,:item3替换成map中对应的“111”,"222","333"

String SQL="insert into table(item1,item2,item3) values(:item1,:item2,:item3)";   
            Map map = new HashMap();  
            map.put("item1","111");   
            map.put("item2","222");   
            map.put("item3","333");   
 
            Pattern p=Pattern.compile("(?::)(\\w+)(?:\\b)");     
            Matcher m=p.matcher(SQL);     
            StringBuffer result=new StringBuffer();     
            while (m.find()) {     
                String key=m.group(1);     
                m.appendReplacement(result,(String)map.get(key));     
            }     
            m.appendTail(result);     
            String resultSql=result.toString();  
            System.out.println(resultSql); 

----------------------------------------------------------------------------------------------------------


(27)求一个去括号()中间任意字符串的JAVA正则表达式
String s="(Jack)jack1@163.com,"+   
      "(杰克)jack2@qq.com,"+   
      "(jack son.()杰克)jack3@qq.com,"+   
      "(杰克.jack)jack4@qq.com,";   
 
String result= s.replaceAll("\\((?<=\\()[^@]+(?=(\\)[^)]+@))\\)","");   
System.out.println("Result:"+result); 
----------------------------------------------------------------------------------------------------------


(28)只匹配 15位 或者 18 位
/^\d{15}$|^\d{18}$/
----------------------------------------------------------------------------------------------------------


(29)要写一个判断金额小于等于20,小数位数只能有1位,不是负数的正则表达式
js: /^(?:20(?:\.0)?|1?\d(?:\.\d)?)$/ 
java: "^(?:20(?:\\.0)?|1?\\d(?:\\.\\d)?)$" 

----------------------------------------------------------------------------------------------------------


(30)正则表达式 用来匹配提取aa,bb的值
   String src1 = "/ssiwh/vieen/;aa=87211_diweuj;bb=wqqeii_998;qq/;/"; 
   String re1  = "(?<=([aa|bb]=))[^;]+(?=;)";
   Pattern p = Pattern.compile(re1);
   Matcher m = p.matcher(src1);
       
   while(m.find()){   
       String tmp = m.group();
       System.out.println("结果:"+tmp);
   }
 ----------------------------------------------------------------------------------------------------------


(31)要求是:只能输入0-24之间的数字,最多只允许两位小数。
var re = /(^[0-9]([.][0-9]{1,2})?$)|(^1[0-9]([.][0-9]{1,2})?$)|(^2[0-3]([.][0-9]{1,2})?$)|(^24([.]0{1,2})?$)/;
或者
/^([1](?:[0-9]|)|[2](?:[0-3]|)|[0-9])(?:\.[0-9]{1,2}|)$|^24(?:\.0{1,2}|)$/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值