加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

常用正则表达式(?i)忽略字母的大小写!

发布时间:2020-12-13 22:57:23 所属栏目:百科 来源:网络整理
导读:1 。 ^ /d + $ // 匹配非负整数(正整数+0) 2 。 ^ [ 0 - 9 ] * [ 1 - 9 ][ 0 - 9 ] * $ // 匹配正整数 3 。 ^ (( - /d + ) | ( 0 + ))$ // 匹配非正整数(负整数+0) 4 。 ^- [ 0 - 9 ] * [ 1 - 9 ][ 0 - 9 ] * $ // 匹配负整数 5 。 ^-? /d + $ // 匹配整

1^/d+$  //匹配非负整数(正整数+0)
2^[0-9]*[1-9][0-9]*$  //匹配正整数
3^((-/d+)|(0+))$  //匹配非正整数(负整数+0)
4^-[0-9]*[1-9][0-9]*$  //匹配负整数
5^-?/d+$    //匹配整数
6^/d+(/./d+)?$  //匹配非负浮点数(正浮点数+0)
7^(([0-9]+/.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*/.[0-9]+)|([0-9]*[1-9][0-9]*))$  //匹配正浮点数
8^((-/d+(/./d+)?)|(0+(/.0+)?))$  //匹配非正浮点数(负浮点数+0)
9^(-(([0-9]+/.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*/.[0-9]+)|([0-9]*[1-9][0-9]*)))$  //匹配负浮点数
10^(-?/d+)(/./d+)?$  //匹配浮点数
11^[A-Za-z]+$  //匹配由26个英文字母组成的字符串
12^[A-Z]+$  //匹配由26个英文字母的大写组成的字符串
13^[a-z]+$  //匹配由26个英文字母的小写组成的字符串
14^[A-Za-z0-9]+$  //匹配由数字和26个英文字母组成的字符串
15^/w+$  //匹配由数字、26个英文字母或者下划线组成的字符串
16^[/w-]+(/.[/w-]+)*@[/w-]+(/.[/w-]+)+$    //匹配email地址
17^[a-zA-z]+://匹配(/w+(-/w+)*)(/.(/w+(-/w+)*))*(/?/S*)?$  //匹配url
18。匹配中文字符的正则表达式:[/u4e00-/u9fa5]
19。匹配双字节字符(包括汉字在内):[^/x00-/xff]
20。应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
String.prototype.len
=function(){returnthis.replace([^/x00-/xff]/g,"aa").length;}
21。匹配空行的正则表达式:/n[/s|]*/r
22。匹配HTML标记的正则表达式:/<(.*)>.*<///1>|<(.*)//>/
23。匹配首尾空格的正则表达式:(^/s*)|(/s*$)

*正则表达式用例
*1^/S+[a-zA-Z]$不能为空不能有空格只能是英文字母
*2、/S{6,}不能为空六位以上
*3^/d+$不能有空格不能非数字
*4、(.*)(/.jpg|/.bmp)$只能是jpg和bmp格式
*5^/d{4}/-/d{1,2}-/d{1,2}$只能是2004-10-22格式
*6^0$至少选一项
*7^0{2,}$至少选两项
*8^[/s|/S]{20,}$不能为空二十字以上
*9^/+?[a-z0-9](([-+.]|[_]+)?[a-z0-9]+)*@([a-z0-9]+(/.|/-))+[a-z]{2,6}$邮件
*10、/w+([-+.]/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*([,;]/s*/w+([-+.]/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*)*输入多个地址用逗号或空格分隔邮件
*11^(/([0-9]+/))?[0-9]{7,8}$电话号码7位或8位或前面有区号例如(02287341628
*12^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(/.[a-zA-Z0-9_]+)+(/,[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(/.[a-zA-Z0-9_]+)+)*$
*只能是字母、数字、下划线;必须有@和.同时格式要规范邮件
*13^/w+@/w+(/./w+)+(/,/w+@/w+(/./w+)+)*$上面表达式也可以写成这样子,更精练。
14^/w+((-/w+)|(/./w+))*/@/w+((/.|-)/w+)*/./w+$







//限定条件
finalStringCONDITION="(?=.*[a-z])(?=.*[A-Z])(?=.*//d)";

//允许出现的字符
finalStringSPECIAL_CHAR="[-A-Za-z0-9!$%&()/;<?{}//[//]^////]";

//数量
finalStringQUANTITY="{8,16}";



1楼的回复

(
?=.*[a-z])表示当前位置后面必须出现.*[a-z]的字符,这个可以理解为必须出现小写字母。
或者可以理解为某一个字符间的缝隙必须满足的条件,这个仅仅作为条件判断并不能匹配任何字
符,因为这属于非捕获组中的环视(lookarround)零宽度匹配。

举个大家常见的例子:

表达式:Win(
?=XP)
现有字符串WinXP和WinNT,在应用这个表达式时前者能与之进行匹配,为什么呢?

当匹配器指示到(
?=XP)时,也就是在n字母后面的缝隙,这个缝隙必须满足的
条件是:后面的字符必须是XP,如果是的话,匹配成功,否则匹配失败。由于
(
?=XP)是匹配缝隙的,因此并不会把XP给匹配输出,而只输出了Win因此,这
个表达式的语义可以看作是:找到后面为“XP”字符所有的Win。

假如,我们把表达式写成Win(
?=XP)(?=NT)这样的话,那么这个语义是:找出后面
为“XP”并且为“NT”字符所有的Win可以想象,这是个
永远无法满足的匹配。(
?=XP)(?=NT)这个表示当前的缝隙必须同时满足的条件。

把这个表达式再改一下,改成Win(
?=.*XP)(?=.*NT)这个表示Win的后面必须出现
XP与NT,位置和顺序都是无关的(这主要是.
*的作用)。当然了这个表达式的效
率是比较低的,得向后进行两次断言。

如果字符串是WincbaXPabcNT这个字符串,当匹配指示器走到n后面的缝隙时开始
进行向后断言,首先对.
*XP进行断言,很明显能将cbaXP匹配成功,这时第一个断
言完成,再对.
*NT断言,可以看出cbaXPabcNT能与其匹配成功,这时第二个断言完
成,因此表达式Win(
?=.*XP)(?=.*NT)能对WincbaXPabcNT进行匹配。

同理WincbaNTabcXP也是同样的效果。

如果能理解上面的这些,对于(
?=.*[a-z])(?=.*[A-Z])(?=.*//d)这个的理应该不会
很难吧,这个只不过是必须同时满足三个条件。

这个表达式在开始部分就进行断言,即索引为
0的地方,也就是第一个字符的前面的
缝隙,这个缝隙后面的字符必须满足.
*[a-z].*[A-Z].*//d三个条件,也就是说
必后面必须出现至少一个小写字母、至少一个大写母、至少一个数字。


至于表达式
2的使用,也就是[]内字符的转义需要注意一下。

^-在[]结构的表达式中是有一定意义的。

[
^abc]表示除abc以外所有的字符,注意,这是放在最前面表示这个意思,
如果改成[a
^bc]这个仅表示a^bc四个字符。如果需要匹配^这个字符
的话,千万不要把它放在第一个,如果一定要放在第一个的话,得使用转义符。

-在[]表示字符的范围,比如[a-z]表示a与z之间的26个字母,
[a
-zA-Z]这个表示a-z和A-Z的52个字母。使用范围得注意了,如果写成
[z
-a]的话,在Pattern.compile编译表达式时会对范围进行检查,这时会产
生异常,因此在使用
-范围时,后面的Unicode值必须大于等于前面的Unicode
值。

如果要匹配“
-”的话,尽量不要把-这个放在字符之间,可以放在[]的两边。
比如[
-a-z]这就能匹配26个小写字母和“-”了。当然了,我们也可以写成
[a
-z-A-Z]这个可以匹配52字母和“-”,但是这样很不直观,我们宁愿写成
[a
-zA-Z-]或者[-a-zA-Z]这样。





2:不以某某开头,比如不以www开头


Javacode
publicclassTest{
publicstaticvoidmain(String[]args){
String[]strs
={"abc1232","wwwadsf","awwwfas","wwadfsf","","ww","","www"};
Stringregex
="(?:(?!^www).)*";
for(Stringstr:strs){

System.out.printf(
"%-7s%s%n",str,str.matches(regex));
}
}
}


(
?!X)专业名称为NegativeLookahead,表示字符间缝隙后面不允许出现的字符,
即匹配字符间的缝隙,如果缝隙后的字符不是X的话,那这个缝隙就匹配成功。

举个例子,aab和aac,现有表达式aa(
?!b)这时我们能匹配到的字符串是aac,
因为aa的后面的缝隙之后不允许出现字符b,因此只有aac进行了匹配。

再来看个示例:

Javacode

publicclassTest{
publicstaticvoidmain(String[]args){
Stringstr
="AQuickBrownFoxJumpsOverTheLazyDog";
String[]strs
=str.split("(?<!^)(?=[A-Z])");
for(Strings:strs){
System.out.println(s);
}
}
}


根据大写字母拆分字符串。当然了,这个使用字符串进行分析同样也能进行拆分,
但是使用正则表达式来拆的话更为便捷直观一些。

在进行这种拆分时,由于在拆分后的字符数不能减少,因此只能使用零宽度的
lookaround功能进行匹配,lookaround包括四个,即:

Javacode
(
?=X)(?!X)(?<=X)(?<!X)


来看一下这个表达式:(
?<!^)(?=[A-Z])

前面说到过(
?!)表示缝隙后面不允许出现的东西,而(?<!)表示缝隙前不允许出现的东西。
(
?=)表示缝隙后允许出现的东西,(?<=)表示缝隙前允许出现的东西。

这个表达式在拆分时,根据零宽度匹配缝隙进行拆分的,这个缝隙必须满足以下条件:

(
?<!^)表示缝隙不允许前不能是行开始,即缝隙不能出现在首字母的前面。
(
?=[A-Z])表示缝隙后面允许出现A-Z的大写字母。

这时这个表达式就匹配了下面带有
|的缝隙:

Javacode
A
|Quick|Brown|Fox|Jumps|Over|The|Lazy|DogPS:不加(?<!^)的话,会变成:|A|Quick|Brown|Fox|Jumps|Over|The|Lazy|Dog


根据split的功能,正则表达式处理程序就根据上面的
|将字符串给拆分开来了。


3,不区分大小写
不加任何限制的匹配是匹配分大小写的,但是正则表达式中可以进行改变,
有两种方式:参数式和内嵌式。

来看个示例:

Javacode
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
publicclassTest{
publicstaticvoidmain(String[]args){
Stringstr
="Book";
Patternpattern
=Pattern.compile("book");
Matchermatcher
=pattern.matcher(str);
System.out.println(matcher.matches());
}
}


上面的这个表达式book是不能匹配字符串Book的,这时我们只要给定编译时的参数就可以了:

Patternpattern
=Pattern.compile("book",Pattern.CASE_INSENSITIVE);

Pattern.CASE_INSENSITIVE这是一个
int类型的常量,值为2。表示表达式忽略大小写进行区配。

如果我们不采用Pattern和Matcher两个类来匹配的话,只是使用String的matches方法的话,
我们就不能指定表达式的编译参数了,这时就需要采用内嵌标志表达式了,与Pattern.CASE_INSENSITIVE
对应的内嵌标志表达式是(
?i),它有四种形式:
1,(?i)
2,(?-i)
3,(?i:X)
4,(?-i:X)
不带有
-的是开标志,带有-的是关标志。

把上面的代码改成这样:

Javacode
publicclassTest{
publicstaticvoidmain(String[]args){
Stringstr
="Book";
Stringregex
="(?i)book";
System.out.println(str.matches(regex));
}
}


我们就达到了同样的效果,当然这样并不是最好的,因为字符串中只有B是大写的,
我们没有必要把所有的字符都进行不区分大小写匹配,我们可以在打开标志,用(
?i)的
第二种形式马上关掉它:
Stringregex
="(?i)b(?-i)ook";

这样的话,只有b是区分大小写了,而(
?-i)后面的还是得区分大小写匹配的。这样写
可能看上去很不顺眼,我们还能使用第
3种形式直接指定某些字符是不区分大小写的。
Stringregex
="(?i:b)ook";

这样的表达式与上面的那个在语义上是相同的。就效率上肯定是优于一下子开,一下子关的。

可见内嵌标志表达式要比指定编译参数的功能强大许多。

使用建议:如果能确定某些字符的大小写时,尽量使用已确定的字符,对于不确定的可以采用
(
?i:X)的方式指定。因此打开不区分大小写开关时,对匹配的性能是有一定影响的。

思考一下:Stringregex
="(?i)b(?-i:oo)k";这个表达式的意思?


另外:第
1和第4,我没看明白需要了解什么,请在下面的楼层中具体地说明一下。



1:多行匹配

在默认的情况下.是不能匹配行结束符的(行结束符有
6个,具体的可以看看Pattern的APIDOC)
同样,可以像不匹配大小写匹配那样使用编译参数:Pattern.DOTALL

如果还得区分大小写的话,还得加上上面说到的Pattern.CASE_INSENSITIVE这个,举个例子:

Javacode
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
publicclassTest{
publicstaticvoidmain(String[]args){
Stringstr
="<table>/n"+"<tr>/n"+"<td>/n"+"HelloWorld!/n"+"</td>/n"+"</tr>/n"+"</table>";
Stringregex
="<td>(.+?)</td>";
Patternpattern
=Pattern.compile(regex);
Matchermatcher
=pattern.matcher(str);
while(matcher.find()){
System.out.println(matcher.group(
1).trim());
}
}
}


上面这个是不能从str抽取出东西的,因为td的后面带有换行符,我们只要更改一下:

Patternpattern
=Pattern.compile(regex,Pattern.DOTALL);

这样就行了,如果td还得不区分大小写的话,再改成:

Javacode
Patternpattern
=Pattern.compile(regex,Pattern.DOTALL|Pattern.CASE_INSENSITIVE);


这样的话,td哪怕是大写的这个表达式都能把td之间的字符区抽取出来。

当然和Pattern.CASE_INSENSITIVE一样,Pattern.DOTALL也有内嵌标志表达式,即(
?s)
s的意思表示single
-line就是忽略换行符什么的,只看成单行进行处理。

这个表达式使用内嵌(
?s)的话可以改为:

Javacode
Stringregex
="(?s)<td>(.+?)</td>";如果还要不区分大小写的话,再加上i标志:Stringregex="(?s)(?i)<td>(.+?)</td>";但这样显得很拖沓,可以把它们合并起来:Stringregex="(?is)<td>(.+?)</td>";//秩序无所谓


最后需要说明一下的是,我曾看到过由于不明白DOTALL,为了让.匹配行结束符,直接把表达式写成:

Javacode
Stringregex
="<td>((.|//s)+?)</td>";


这样做是极其危险的,由于选择结构的匹配效率问题,这样做在比较长的字符串时会造成堆栈溢出,
使程序崩溃,如果使用DOTALL或者(
?s)的话就不会出现这种情况。


4:2个单元的或操作

|称为多选结构,用于匹配|之中的任何一个,拿你的例子来说明:

Javacode
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
publicclassTest{
publicstaticvoidmain(String[]args){
Stringstr
="<imgsrc=/"http://www.google.com/1.gif/"/>/n"+"<imgsrc=/"http://3w.google.com/1.gif/"/>/n"+"<imgsrc=/"http://abc.baidu.com/1.gif/"/>";
Stringregex="<img//ssrc=/"http://(?:ww|3)w.google.com/1.gif/"/>";
Patternpattern=Pattern.compile(regex);
Matchermatcher
=pattern.matcher(str);
while(matcher.find()){
System.out.println(matcher.group());
}
}
}


注意到其中的(
?:ww|3)在进行多选匹配时尽量找出多选中的规律,以减少多选的字符,
www和3w在最后一个字符可以共用,前面的不一样。

(
?:)的意思表示组成一组,如果没有(?:)这样的话,表达式就变成了:

Javacode
Stringregex
="<img//ssrc=/"http://ww|3w.google.com/1.gif/"/>";


这样的语义完全变掉了,
|是在一组中进行选择,由于上面的那个表达式中没有组,就把整个表
达式作为了一组,使用
|的话,就进行了整个表达式的多选结构了。这个表达式的意思是:
匹配
<imgssrc="http://ww或者是3w.google.com/1.gif"/>,这样的结果并不是我们所要的。

我们仅仅需要在ww和
3之间进行选择,这时只要把ww和3放在一组中进行多选择就可以了,
变成(
?:ww|3)。

还有,在多选结构中尽量把出现频率高的放在前面,这样可以加快匹配速度。

多选结构的效率在传统型的引擎中是效率低下的,如果是单个字符的选择,比如a$
&之中的一个,
那就不要使用(
?:a|$|&)了,可以直接使用字符类[a$&]就可以了。 说了那么多,不知道是否明白了?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读