最近写了好几个关于正则的例子,第一个是过滤WordPress的数据库文章中的图片链接,另一个是写一个app时候要判断一个表达式是否符合逻辑,是时候把这些积累的东西给堆出来了,毕竟,谁都记不了那么清楚啊!!!
第一篇博文内容:特例解释(请关注其用法,而不是示例用的什么语言,Perl,java?随他呢)
(1) 点号(.),它用来匹配任意一个单字符(\n 排除在外,后面我默认不再提这个例外)。
所以: "twoon" =~ /tw.on/ 为 true “twvon" =~ /tw.on/ 也为 true.
点号在正则表达式中是有特殊含义的,有时我们可能也要匹配点号,这时就需要转义一下。
"twoo.n" =~ /twoo\.n/ 为true.
正则表达中,所有其它的通配符也都可以用同样的方式进行转义,表示直接匹配通配符,去除它的特殊含义。
你可以看到\也是一个通配符,如果要匹配它也是同样的道理。
"two\\on" =~ /two\\on/ 为true.
(2) 星号(*) : 星号代表匹配它前面一个字符任意遍(0或任意次),它是一数量词(quantifier),必须跟在其它字符的后面,否则这个表达式不正确。如:
”twoon" =~ /two*n/ 为true “twn" =~ /two*n/ 也为true. "twoon" =~ /*twoon/ 表达式不正确,*必须跟在其它符号后面.
同时星号也可以匹配点号(.),点号代表任意非回车字符,因此, (.*)就代表任意字符任意次。这是一个惯常的用法,如:
/twoon.*walks/ 能匹配任意包含"twoon"在前,"walks“在后的字符串。
所以(.*)也被称为:any old junk. 匹配任何东西。
(3) 加号(+): 加号是一个与星号(*)类似的通配符,它也是数量词,表示匹配前面的字符一次或多次(至少一次).
它与星号的差别就在这里,星号可以匹配0次,加号则必须一次以上。 如:
"twoon" =~ /two+n/ 为true. "twn" =~ /two+n/ 为false.
(4) 问号(?): 问号也是一个数量词,它代表匹配前一个字符0或1次。如:
"twoon" =~ /twoo?n/ 为true "twoon” =~ /two?n/ 为false. "twn" =~ /two?n/ 为true.
(5) 括号(()): 括号用来表示一个组合,前面我说数量词作用在前一个字符上,这个说法事实上不准确,应该说是作用在一个组合上,一个字符是一个组合,但多个字符也可以成为组合。括号就是用来表示一个组合,被括号括起来的就是一个组合。如:
"twoon" =~ /tw(o)*n/ 为true. "twoon" =~ /tw(oo)*n/ 为true "twowon" =~ /t(wo)*n/ 为true. "twoon" =~ /t(wv)*oon/ 为false. “twoon" =~ /t(wo)+on/ 为true. “twon" =~ /t(wo)+on/ 为false.
括号里可以放置任何字符,也可以放置其它通配符,如 “aaabcc” =~ /(aa+b)?cc/
(6) 引用通配符:反斜杠加上数字是所谓引用通配符(back reference): \1 \2 \3 等,它的作用是引用前面的某个括号元组,如:
"twoonwo" =~ /t(wo)on\1/ 为true
乍看起来,似乎作用不明显,如上例,我们完全可以不用\1,而写成这样: /t(wo)on(wo)/
在上面的例子里,这个质疑是可以理解的。但有时,我们的括号元组可能这样写的: (we…) 因为点号代表任意字符,如果我们后面要作用这个元组,不用引用通配符, 我们根本无法引用,具体看例子:
”weabceeweabc" =~ /(we...)ee\1/ 为 true。 “weabceeweabc" =~ /(we...)ee(we...)/ 为 true ”weabceewecdf" =~ /(we...)ee(we...)/ 也为 true.
从第2,3个例子,我们可以看区别。\1 表示的是与前一个元组完全一样的匹配。而 \1,\2,\3等,则分别表示,从左往右数第几个元组。
“abcdef def abc" =~ /(...)(...) \2\1/ 为 true.
在 perl 中,引用通配符中支持从1~9,写法上很活,你既可直接\1 \2 …\9这样来写,也可以写成 \g{1] ,\g{2},…..\g{9}。后面一种写法相对复杂些,但有助于perl来理解你想表达的含义。因为反斜杠在程序语言中有特殊的信念,通常表达转义,perl 在遇到反斜杠时,它会去猜你想表达的什么。所以如果你写一个类似: \123这样的东西,它就不知怎么去解析,你是想表达 \1+23,引用后面跟着数字,还是,\12+3,或 \123,转义符后面跟数字是可以表示转义一个8进制数字的。因此这里产生了歧义。perl 5.10 于是引入了 \g{N}这种表述方式来表示引用通配符。N 甚至可以是负数,当是用负数是,它表示一个相对位置。表示从当前位置开始往左数,第N个元组,如:
"twooavvboonn" =~ /tw(oo)a(vv)b\{-2}(nn)/ 为true
(7) 中括号[]: 中括号用来表示一个字符集合(character set)
字符集合,顾名思义,就是字符的集合,集合的元素放在中括号里,表示每次匹配中其中的一个,如:
"twoon” =~ /[tw]woo/ 为 true
有时如果这个集合有很多元素,如26个字母,数字等,一个个地写在中括号里,未免太麻烦太蠢笨,这时可以用连字符(hyphen)来表示一个范围,
如:[a-z]表示小写字母的集合,[a-zA-Z]表示大小写字母的集合。
上面的用法用于提供范围来选择,但有时不匹配某个范围也是很常见的匹配需求,这时我们可以在集合的开头放一个脱字符 ^ (caret). 这种写法表示,匹配任何不在该集合中的字符,与上面的用法刚好相反。如:
"twoon" =~ /[^two]woon/ 为false “ewoon" =~ /[^two]woon/ 为true
由上面的用法,可知 ^,- 这两种符号在集合中有特殊含义,如果我们们想在集合中表示这两个字符,就也要转义一下。如:
[\^ab\-]
有些字符集合是很常用的,如字母,数字等,perl提供了一些缩写来表示这些常用的集合,如:\d表示一个数字,等价于[0-9],这些特殊字符包括如下 :
\w -- (小写w) 表示字母或数字,等价于 [a-zA-Z0-9] \W -- (大写W)非字母且非数字,与\w相反 \s -- (小写s)匹配一个空格字符,包括:空格,换行,回车,tab,等价于[ \n\r\t\f] \S -- (大写S)匹配非空格字符,\s的相反 \d -- 表示10进制数字,等价于 [0-9]
(8) 大括号:{}
大括号的作用是指定重复前面一个字符多少遍:
{N} 重复N遍 {n,m} 重复 n~m 遍 {n,} 至少重复n遍 {,m} 至多重复m遍 示例:"twoon" =~ /two{2}n/ 为true.
(9) ^,& 这两个通配符用来表示在匹配串的头部或尾部匹配。
一般我们写这种: “twoon” =~ /oo/ 正则表达式的时候,匹配是从”twoon”的开始一路匹配下去,如tw != oo,就继续往下匹配,但有时候我们可能只想匹配一下开头或结尾,这时^,&就派上用场了。^用于匹配字符串的开关,&用于匹配字符串的结尾。如:
"twoon" =~ "^tw" 为true. “twoon” =~ “oo" 为true "twoon" =~ "^oo" 就为false. ”twoon" = "on&" 为true. "twoon“ = ”oo&" 为false
(10) “或” 通配符: 正则表达式用竖线 | 表示或, (ab | cd) 表示匹配竖线左右的字符组之一,如果左右的字符数超过一个,它必须和括号一起使用。如:
"twoon” =~ /t|ewoon/ 结果为true "twoon" =~ /(tw|ee)oon/ 结果为true "twoon" =~ /(ee|gs)oon/ 结果为false
第二篇博文:入门的符号说明(并未全部验证,复制粘贴可能有错,自行尝试,仅供参考)
// 反斜杠 /t 间隔 ('/u0009') /n 换行 ('/u000A') /r 回车 ('/u000D') /d 数字 等价于[0-9] /D 非数字 等价于[^0-9] /s 空白符号 [/t/n/x0B/f/r] /S 非空白符号 [^/t/n/x0B/f/r] /w 单独字符 [a-zA-Z_0-9] /W 非单独字符 [^a-zA-Z_0-9] /f 换页符 /e Escape /b 一个单词的边界 /B 一个非单词的边界 /G 前一个匹配的结束 ^为限制开头 ^java 条件限制为以Java为开头字符
第三篇文章:正则的搬运工(现成的,基本拿到就可以用,当然你要解析写法我也没意见)
第四篇:怎么用?(Java正则示例)
查找以Java开头,任意结尾的字符串
Pattern pattern = Pattern.compile("^Java.*"); Matcher matcher = pattern.matcher("Java不是人"); boolean b= matcher.matches(); //当条件满足时,将返回true,否则返回false System.out.println(b);
以多条件分割字符串时
Pattern pattern = Pattern.compile("[, |]+"); String[] strs = pattern.split("Java Hello World Java,Hello,,World|Sun"); for (int i=0;i<strs.length;i++) { System.out.println(strs[i]); }
文字替换(首次出现字符)
Pattern pattern = Pattern.compile("正则表达式"); Matcher matcher = pattern.matcher("正则表达式 Hello World,正则表达式 Hello World"); //替换第一个符合正则的数据 System.out.println(matcher.replaceFirst("Java"));
文字替换(全部)
Pattern pattern = Pattern.compile("正则表达式"); Matcher matcher = pattern.matcher("正则表达式 Hello World,正则表达式 Hello World"); //替换第一个符合正则的数据 System.out.println(matcher.replaceAll("Java"));
文字替换(置换字符)
Pattern pattern = Pattern.compile("正则表达式"); Matcher matcher = pattern.matcher("正则表达式 Hello World,正则表达式 Hello World "); StringBuffer sbr = new StringBuffer(); while (matcher.find()) { matcher.appendReplacement(sbr, "Java"); } matcher.appendTail(sbr); System.out.println(sbr.toString());
验证是否为邮箱地址
String str="ceponline@yahoo.com.cn"; Pattern pattern = Pattern.compile("[//w//.//-]+@([//w//-]+//.)+[//w//-]+",Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(str); System.out.println(matcher.matches());
去除html标记
Pattern pattern = Pattern.compile("<.+?>", Pattern.DOTALL); Matcher matcher = pattern.matcher("<a href=/"index.html/">主页</a>"); String string = matcher.replaceAll(""); System.out.println(string);
查找html中对应条件字符串
Pattern pattern = Pattern.compile("href=/"(.+?)/""); Matcher matcher = pattern.matcher("<a href=/"index.html/">主页</a>"); if(matcher.find()) System.out.println(matcher.group(1)); }
截取http://地址
Pattern pattern = Pattern.compile("(http://|https://){1}[//w//.//-/:]+"); Matcher matcher = pattern.matcher("dsdsds<http://dsds//gfgffdfd>fdf"); StringBuffer buffer = new StringBuffer(); while(matcher.find()){ buffer.append(matcher.group()); buffer.append("/r/n"); System.out.println(buffer.toString()); }
替换指定{}中文字
String str = "Java目前的发展史是由{0}年-{1}年"; String[][] object={new String[]{"//{0//}","1995"},new String[]{"//{1//}","2007"}}; System.out.println(replace(str,object)); public static String replace(final String sourceString,Object[] object) { String temp=sourceString; for(int i=0;i<object.length;i++){ String[] result=(String[])object[i]; Pattern pattern = Pattern.compile(result[0]); Matcher matcher = pattern.matcher(temp); temp=matcher.replaceAll(result[1]); } return temp; }
最后附上我自己的两个案例:
匹配类似+59.00-59.0,就是完成一个浮点数的加减表达式
((\\-|\\+)?\\d+(\\.\\d+)?)*
匹配HTML的图片标签
/[a-z]{2}-[a-z]{7}/[A-Za-z|-|/|.|0-9]+(.jpg|.png|.gif|.zip|.gz|.7z|.rar|.txt|.bz2
本站由以下主机服务商提供服务支持:
0条评论