关于正则表达式的小笔记

来源:互联网 发布:redis数据存储在哪里 编辑:程序博客网 时间:2024/05/17 12:20

关于正则表达式的小笔记

1.1概述

      正则表达式是一种强大而灵活的文本处理工具。使用正则表达式,我们能够以编程的方式,构造复杂的文本模式,并对输入的字符串进行搜索。一旦找到了相匹配的部分,就能随心所欲进行处理。

      在java语言中的正则表达式对反斜杠\有着与其它语言不同的处理。其它语言中,\\表示“想要在正则表达式中插入一个普通的反斜线,没有任何特殊的意义”;而在java中,\\表示“要插入一个正则表达式的反斜线,因此其后的字符具有特殊的意义。”如:表示一位数字,用\\d表示。

1.2创建正则表达式

表1-1

字符

B

指定字符B

\xhh

十六进制值为oxhh的字符

\uhhhh

十六进制表示为oxhhhh的Unicode

\t

制表符Tab

\n

换行符

\r

回车

\f

换页

\e

转义(Escape)

      只有学会使用字符类之后,正则表达式的威力才能真正显现出来。以下是一些创建字符类的典型方式。

表1-2

字符

.

任意字符

[abc]

包含a、b和c的任意字符(和a|b|c作用相同)

[^abc]

除了a、b和c之外的任何字符(否定)

[a-zA-Z]

从a到z或从A到Z的任何字符(范围)

[abc[hij]]

任意a、b、c、h、i和j字符(和a|b|c|h|i|j作用相同)

[a-z&&[hij]]

任意h、i或j(相交)

\s

空白符(空格、tab、换行、换页和回车)

\S

非空白符([^\S])

\d

数字[0-9]

\D

非数字[^0-9]

\w

词字符[a-zA-Z0-9]

\W

非词字符[^\w]

 

表1-3

逻辑操作符

XY

Y跟在X后面

X|Y

X或Y

(X)

捕获组,可以在表达式中用\i引用第i个捕获组

 

表1-4

边界匹配符

^

一行的起始

$

一行的结束

\b

词的边界

\B

非词的边界

\G

前一个匹配的结束

 

举个例子:

public class Demo{   public static void main(String[] args){         for(String str:new String[]{"Rudolph","[rR]udolph","[rR][aeiou][a-z]ol.*","R.*"}){              System.out.println("Rudolph".matches(str));         }   }}

[rR]udolph:r或R开头;

[rR][aeiou][a-z]ol.*:r或R开头,第二个字母[aeiou]中一个,第三个[a-z]中一个,后接ol,最后为任意字符;

R.*:R打头的任意字符串。

1.3量词

量词描述了一个模式吸收输入文本的方式:

  • 贪婪型:量词总是贪婪的,除非有其他的选项被设置。贪婪表达式会为所有可能的模式发现尽可能多的匹配。假如现有模式仅能匹配第一个可能的字符组,如果它是贪婪的,那么它就会继续匹配下去。
  • 勉强型:用问号来指定,这个量词匹配满足模式所需的最少字符数。所以也称为懒惰的、最少匹配的和非贪婪的。
  • 占有型:这种类型只有在java语言中才可用,当正则表达式被应用于字符串时,它会产生相当多的状态,以便在匹配失败时可以回溯。常用于防止正则表达式失控。

贪婪型

勉强型

占有性

匹配

X?

X??

X?+

一个或零个X

X*

X*?

X*+

零个或多个X

X+

X+?

X++

一个或多个X

X{n}

X{n}?

X{n}+

X恰好出现n次

X{n,}

X{n,}?

X{n,}+

X至少出现n次

X{n,m}

X{n,m}?

X{n,m}+

X至少出现n次,且不超过m次

           注:这里的表达式X,要使用圆括号括起来,如(abc)+。

1.4Pattern和Matcher

虽然String类中也能使用正则表达式,但其功能有限,所以更愿意使用功能强大的regex包下的Pattern.complie()方法来编译正则表达式。

  1.  会更根据正则表达式生成一个Pattern对象;
  2.   然后将要检索的字符串传入Pattern对象的matcher()方法;
  3.   matcher()方法会生成一个Matcher对象。

public class Test{   public static void main(String[] args){         for(String str : args){               Pattern p = Pattern.compile(str);              Matcher m = p.matcher(args[0]);              while(m.find()){                    m.group();                    m.start();                    m.end();              }         }   }}

1.4.1  find()

  Matcher.find()方法可用来在Test中查找多个匹配,find()对字符串进行匹配,匹配到的字符串可以在任何位置。

  find(int i) 重置匹配器,然后尝试查找匹配该模式、并以指定索引i开始匹配。如下代码:

@Test   public void run(){         String s = "hello world";         Pattern p = Pattern.compile("\\w+");         Matcher m = p.matcher(s);         int i = 0;         while(m.find(i)){              System.out.println(m.group());              i++;         }   }/*outputhelloellollolooworldworldorldrldldd*/

1.4.2 组(groups)

Matcher对象提供了一系列方法,用以获取与组相关的信息:

  • l  int groupCount()返回该匹配器的模式中分组数目;
  • l  String group(int group)返回在以前匹配操作期间由给定组捕获的输入子序列。
  • l  int start()返回以前匹配的起始位置的索引。
  • l  int start(int group)返回在以前的匹配操作期间,由给定组所捕获的子序列的起始索引。
  • l  int end()返回最后匹配字符的索引加一的值。
  • l  int end(int group)返回在前一次匹配操作中,寻找到组的最后一个字符索引加一的值。
  • l  boolean matches()只有在完全匹配正则表达式才会返回true。
  • l  boolean lookingAt()尝试将从区域开头开始的输入序列与该模式匹配,只要输入的第一部分匹配就返回true。

1.5split()

split()方法将输入字符串断开成字符串对象数组,断开边界由下列正则表达式确定:

  • l  String[]split(CharSequence input)围绕此模式的匹配拆分给定输入序列。
  • l  String[]split(CharSequence input, int limit)围绕此模式的匹配拆分给定输入序列。注:limit可限定通过分割符分割后的字符串数量。

1.6替换操作

  • l  String replaceAll(Stringreplacement)替换模式与给定替换字符串相匹配的输入序列的每个子序列。
  • l  String replaceFirst(Stringreplacement)替换模式与给定替换字符串匹配的输入序列的第一个子序列。
  • l  Matcher appendReplacement(StringBuffersb, String replacement)执行渐进式的替换。
  • l  StringBufferappendTail(StringBuffer sb)在执行一次或多次appendReplacement()之后,此方法可以将匹配完后剩下的部分复制到sb中。

1.7reset()

Matcher reset()方法可以重置匹配器,将现有的Matcher对象应用于一个新的字符序列。

1.8Pattern标记

static Pattern compile(String regex, int flags)将给定的正则表达式编译到具有给定标志的模式中。

编译标记

效果

Pattern.CANON_EQ

两个字符当且仅当它们的完全规范分解相匹配时,就认为它们是匹配的。例如,如果我们指定这个标记,表达式a\u030A就会匹配字符串?。在默认的情况下,匹配不考虑规范的等价性。

Pattern.CASE_INSENSITIVE(?i)

默认情况下,大小写不敏感的匹配假定只有US-ASCII字符集中的字符才能进行。这个标记允许模式匹配不必考虑大小写(大写或小写)。通过指定UNICODE_CASE标记及结合此标记。基于Unicode的大小写不满干的匹配就可以开启了。

Pattern.COMMENTS(?x)

在这种模式下,空格符将被忽略掉,并且以#开始直到行末的注释也会被忽略掉。通过嵌入的标记表达式也可以开启Unix的行模式X。

Pattern.DOTALL(?s)

在dotall模式中,表达式"." 匹配所有字符,包括终结符。默认情况下,”." 表达式不匹配行终结符。

Pattern.MULTILINE(?m)

在多行模式下,表达式^和$分别匹配一行的开始和结束。^还匹配输入字符串的开始,而$还匹配输入字符串的结尾。默认情况下,这些表达式仅匹配输入的完整字符串的开始和结束。

Pattern.UNICODE_CASE(?u)

当指定这个标记, 并且开启CASE_INSENSITIVE时,大小写不敏感的匹配将按照与Unicode标准相一致的方式进行。默认情况下,大小写不敏感的匹配假定只能在US-ASCII 字符集中

Pattern.UNIX_LINES(?d)

在这种模式下,在., ^和$行为中, 只识别行终结符\n

以上表格摘自《java编程思想》