[原创] 正则表达式学习总结

                         JAVA  正则表达式

A:在代码中使用正则表达式的三种写法:

 其中Pattern类和Match类使用的时候,需要

 import java.util.regex.Pattern;

 写法一:

      public static void printPattern1()

  {

      String str="123";

      String regex="[\\d]{3}";

      //初始化Pattern正则表达式类

      Pattern pattern = Pattern.compile(regex); 

      //初始化Matcher匹配类

       Matcher m = pattern.matcher(str);

       m.matches();// 得到匹配结果true或者false

       System.out.println(m.matches());

  }

  

  写法二:

    public static void printPattern2()

  {

      String str="123";

      String regex="[\\d]{3}";

      System.out.println(Pattern.matches(regex, str));

  }

写法三:

   直接利用String中的Match进行比较

public static void printPattern3()

    {

    String str="123";

      String regex="[\\d]{3}";

      System.out.println(str.matches(regex));

   

}

B 正则表达式验证规则解析说明(java中的)

 

 

首先要声明一点的是:

  ^ 匹配的是一个字符,而不是整个字符串。比如^Java至少要匹配J字母一次,然后后面的ava这些是紧挨着进行输出的。因为字符串是由单个字符组成的,所以不可能允许去匹配整个串的

关于[abc] 这种匹配的说明,这种表示的意思是匹配a或者b或者c,只能匹配其中的一个字符。

 [a-z]

    在匹配az这中间所有的小写字母时候为以上写法

    上面的[a-z]就等价于

    [abcdefghijklmnopqrstuvwxyz]

针对上面的我们可以abcd的匹配,我们可以将条件改为[a-d]

 

[a-z]中间的-这个显然是一种很好的做法,如果我们要匹配的一些字符太多。那挨个写出来的话,会不会感觉到很崩溃。

同理匹配[A-Z] 26个大写字母

那么问题来了,我这里面要匹配所有的英文大小写字母咋办那?

有的小伙伴可能会说我可以这样啊

[a-z][A-Z] 很聪明,的确这是一种做法。

不过还有这种[a-zA-Z] 这种实际上就是[a-z][A-Z]的缩写形式

别问我为什么会这样写。自己摸索吧

好了我们要匹配0-910个任意字符应该怎么写那?

[0-9]

同理我们模仿以上的写法,可以自由组合出:

  总结一下[]这种的用法:

  [a-z] 等价于[abcdefghijklmnopqrstuvwxyz]

  [a-zA-Z] 等价于[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVwXYZ]

  等价于[a-z[A-Z]]这种写法,等价于[a-zA-Z];

 

 有的小伙伴可能会说了[]里面的- 这么强大,那么我想用[a-zA-Z],我可以直接

 [A-z]表示吗?来试一下

 备注:

 因为AASCI码为65,而小aASCI码为97,所以A-zASCI码会包含所有的

 a-z A-Z之间的所有范围。来让我们实践一下

以下结果说明什么了,是可以的。

有的小伙伴或者脑洞打开,会想到,如果我把条件写成这样,会得到什么

 [z-a];

小伙伴们被惊呆了吧。别怕。由此我们想到这是人家由小到大的规定

好了,有的小伙伴可能会说了,以上是固定的a-Z或者A-Z,而我想要在匹配条件中

要加入自己定义的_或者—或者.咋办那?

看完这个例子,是不是瞬晕了,那么多- - ,别急,我们分析一下:

 [a-z-A-Z] 表示的是匹配a-Z或者A-Z或者-

 你也可以这样写:[a-zA-Z-]

接下来我们看一下这种情况:

[^abc] 这种表示的是匹配非a ,非b,非c那,还是匹配的是非ab或者c那?

有的小伙伴会说第二种吗?有的说当然是第一种,瞬间都快打起来了。别急,遇到

问题,写一遍,就得到答案了。

 

[]中加入^后加再次限制条件「[^]
[^a-z]     条件限制在非小写a to z范围中一个字符
[^A-Z]     条件限制在非大写A to Z范围中一个字符
[^a-zA-Z] 条件限制在非小写a to z或非大写A to Z范围中一个字符
[^0-9]     条件限制在非小写0 to 9范围中一个字符
[^0-9a-z] 条件限制在非小写0 to 9或非a to z范围中一个字符
[^0-9[a-z]] 条件限制在非小写0 to 9或非a to z范围中一个字符(交集

//a-z中除掉s v的字符。用^的话咋实现那?

 

 貌似没有什么好的方法。

 

 针对以上的情况,为了省事,有些写法还有如下表达式

接着我们来看验证正则规则2

好多啊,会不会吓坏了,别怕,其实很简单。

[abc]这种的啥都不写的,默认验证一次,其中可以为ab或者c

实际上也就相当于

[abc]==[abc]{1}==[abc]{1,1}

[abc]?匹配0次或者1次,其中0次默认为””的这种形式,而不是其他的除去

a,b,c的这三个字符。

[abc]?匹配的是abc这个整体那,还是a或者b或者c这个单个字符那,单个字符

匹配一次或者多次的话[abc]+这种

因为+表示的是1次或者多次,如果是0次的话,则为false。

其实在匹配”ab” 的时候,因为[abc]里面可以任意匹配a或者b,所以先第一次匹配a

表示成功,又因为[abc]+后面有这个+所以会又可以再次追加任意多个字符进行匹配,第二次匹配字符b,b属于[abc]中的范畴,所以匹配成。

[abc]*这种,匹配 0次,1次,或者多次

总结:

  X*  如果X[abc]的话则会匹配abc中的其中的一个元素进行大于等于0次的匹配

      如果将X改为abc*这种形式那,则只会匹配abccccc 这种形式的,是针对字符c进行0次或者多次匹配

      如果要将abc做为整体匹配,想要输入abcabc正确,abccb这种错误的那

      此时就必须要见万能的() 括号了,做为一个整体,进行匹配。(abc)*

     以上代码为:

 

小练习:

1

String str2="[a-z]*";
System.out.println("".matches(str2));

 

结果:true;

分析:实际上就是匹配a到z中的字符0次或以上

2

String str3="\\d?[a-z]*";
System.out.println("123abc".matches(str3));

 

结果:false

分析:

\d?只能匹配0次或者1次,所以只能匹配到1

后面的2和3不在[a-z]范围之后,所以会为false

如果改为这种则正确:

String str3="\\d*[a-z]*";
System.out.println("123abc".matches(str3));

结果:true

String str3="\\d+[a-z]*";
System.out.println("123abc".matches(str3));

 

结果:true

3》记住转义字符为\. 而不是/ 在输出+字符时候时候必须为 //+

 

String str4="(/+86|0086)?\\b{2}";
System.out.println("+8612".matches(str4));

 

结果:

 

如这种:

[a-z]+[0-2]{1,2}

此处的+相当于[a-z]+输出一次或者多次。如果要想输出a+12 这种形式的话,就必须使用转义\\+了

 

 

 

 

 

//注释块的时候Ctrl+Shit+/ 去掉块注释的时候Ctrl+Shit+\

 

因为正则表达式中要表示\\这种形式就需要首先给每个进行转型

     m.matches 不会吐出

 

     

理解 Java 正则表达式怪异的 \\ \\\\,让您见怪不怪

2010-11-29 — Unmi

Java 语言里的几大变革,一为 jdk1.4 引入的正则表达式,jdk1.5 引入的泛型。没有泛型之前有不少人曾想方设法从编译器入手让 Java 支持泛型。说到泛型  Perl 无疑是该方面的佼佼者,虽然我们不要求 Java 的正则表式能像 Perl 那样可以用来写诗,但至少能有 JavaScript 好用些,可是还不如。JavaScript // 两斜线一框就是一个模式,分组和后向引用更方便,当然前面那两家伙是动态的,不太好比。

复杂的用法不说,且说 Java 的正则表达式在匹配点(.)  和斜杠(\),表达式要分别写作 \\.  \\\\ 难看些,不好理解。幸好还有些人记住了,匹配点(.)   {[(?$^ * 这些特殊符号要要前加双斜框,匹配 \ 时要用四斜杠,这确实能让你包走天涯的。那么为什么是这样呢,不是一个斜杠、三个或更多呢,所以知其然还要知其所以然,这样才能每次心中有数,方能以一变 应万变。

首先,Java 的正则表达式语法说明参见:http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html

最简单的例子来说明问题吧,不创建 PatternMatcher 等对象,就看 String 对象的 replaceAll(String regex, String replacement),它第一个参数接收的就是一个正则表达式,我们可以在 IDE 里的调试器中看 "a.b".replaceAll(".","") 能不能得到你期望的结果。

先说为什么像点号(其他的特殊符号还有引号中的 "{[(?$^ *")前面要加双斜杠,注意逗号(,) 不是这一类特殊字符,因为它只会出现在中括号或花括号中。

显然,如果直接执行

1

"a.b".replaceAll(".","");  //返回空字符串

得到的值不是你想要的结果,成空字符串了,因为点号 "." 匹配了所有的字符,那要只匹配点号该如何呢,对的,双斜杠

1

"a.b".replaceAll("\\.","");  //对的,得到的是 ab

那为什么是双斜杠呢?这个很简单,因为点号(.),是个特殊字符,所以它前面需要需要加个斜杠给它转义,你要真只用一个斜杠来转义,问题就来了,提示你:

Invalid escape sequence (valid ones are \b \t \n \f \r \" \' \\)也就是 Java 不认 \. 序列,所以还需要前面再加一道杠给其后的斜杠转义出一个斜杠给点号(.) 用,也就是在 Java 字符串看起来是 “\\.”, 但作为正则表达式来说就是 “\.”,这于其语言的正则表达式是一致的。

就是说 Java 的正则表达式字符串有两层次的意义,那就是 Java 字符串转义出符合正则表达式语法的字符串,“\\.”, 转义后交给正则表达式的就是 “\.”,这是符合传统的。因为我们平时字符串转义后直接用于输出,所以带来不少误解,这里的最终的正则表达式就是 Java 字符串的输出。

细心的同志一定能看到在调试器里的显示,看我们写成的“\\.”, 在调试器里显示的是 “\\\\.”,说的是如果我们要得到 “\\.”,这样的输出那 Java 的字符串就必须写成 “\\\\.”, 两个斜杠转义出一个斜杠。

的,理解了上面的由来,我们来看看用四个斜杠来匹配一个斜杠的原理。主要原因是斜杠 \ 本身就是用于转义别的字符的,当然它的架子不是一般的大。因为正则表达式串就是 Java 字符串的输出,正常思维在正则表达式里匹配斜杠用 “\\”, 那么在 Java 程序里向控制台输出 “\\”双斜杠该如何写呢,对了,就是 “\\\\”,就这么简单。

再一次从错误里找下原因吧,假如我们写成:

1

"a\\b".replaceAll("\", "");

报什么错呢?String literal is not properly closed by a double-quote,因为斜杠把其后的双引号给转义了,当然字符串是未结束。再给它加个斜杠又如何呢?

1

"a\\b".replaceAll("\\", "");

Java 的语法是通过了,但是执行正则表达式不干了,你转义出来的交给正则表达式的一个斜杠,叫它情何以堪,该去转义谁呢?所以运行时异常报 An exception occurred: java.util.regex.PatternSyntaxException

如果写成三个斜杠呢?

1

"a\\b".replaceAll("<a>\\\</a>", ""); //与单个斜杠是一样的异常,挂单的斜杠把双引号给转义了

所以这样推来推去也是该写成

1

"a\\b".replaceAll("<a>\\\\</a>", "");

对于正则表达式看到的就是 “\\”,哪种语言的正则表达式要的也是这个,也是第一个斜杠转义了第二个,第三个转义了第四个,最终就是 “\\”,正则表达式里转互相转义一下就是 “\”了。

我原来理解还只是停留下转义啊,再转义的基础上,随着写这篇才更加理解到其中要义的,才发现,原来 Java 的正则表达式和其他语言的正则表达式语言是统一的。只要记住一点,你要想的正则表达式字符串是什么,而正则表达式字符串就是 Java 字符串的的输出结果,你就知道应该怎么写了

最后来看下 Eclipse 调试器里仅匹配单个斜杠时,IDE 里显示的有多疯狂:

这让你体验到四个斜杠又何其多也。注:全文中的斜框标准意义上应该叫做反斜杠,在此就不作全文替换了。

 

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/qq_29956725/article/details/81380317