您的位置:首页 > 编程语言 > Java开发

java流与文件——正则表达式

2016-01-18 09:09 399 查看

【0】README

0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件——正则表达式 的相关知识;

0.2) there are my original source code below, and for them , please visit https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter1/RegularExprTest.java

【1】正则表达式相关

1)正则表达式定义: 正则表达式用于指定字符串的模式, 你可以在任何需要定位匹配某种特定模式的字符串的情况下使用正则表达式;

2)看个荔枝:

[Ji]ava.+

2.1)匹配下列形式的所有字符串:

第一个字母是 J 或 j;

接下来3个字母是 ava;

字符串的其余部分是一个或多个任意的字符构成;

3)正则表达式的语法:

3.1)字符类:是一个括在括号中的可选择的字符集,如[Jj], [0-9], [A-Za-z]或[^0-9]; (干货——正则表达式中的字符类[] )

3.2)如果字符类包含 “-”,那么它必须是第一项或最后一项; 如果要包含“[”,那么它必须是第一项; 如果要包含“^”,那么它可以是除开始位置之外的任何位置。其中, 你只需要转义 “[” 和 “\”;

3.3)有许多预定的 字符类: 例如\d(数字) 和 \p{Sc};

3.4)大部分字符都可以与它们自身进行匹配;

3.5)符号可以匹配任何字符;

3.6)使用 \ 作为转义字符, 例如 . 匹配句号 而 \ 匹配反斜线;

3.7) ^ 和 $ 分别匹配一行的开头和结尾;

3.8)如果 X 和 Y 是 正则表达式, 那么XY 表示“任何X的匹配后面跟随Y的匹配”, X|Y表示 “任何 X 或 Y 的 匹配”;

3.9)你可以将量词运用到表达式: X:X+(1个或多个), X*(0个或多个), 与 X?(0个或1个);(干货——将量词 + ,*,?运用到表达式)



3.10)默认情况下: 量词要匹配能够使整个匹配成功的最大可能的重复次数。你可以修改这种行为, 方法是使用后缀?或使用 后缀 + ;

3.11)荔枝: 字符串cab 匹配 [a-z]ab, 但不匹配[a-z]+ab;

对以上荔枝的分析(Analysis): (干货——正则表达式中的贪婪匹配问题)

A1)第一种case中: 表达式[a-z]* 只匹配字符c, 字符ab 匹配剩余部分;

A2)第二种case中: 贪婪版本 [a-z]*+ 将匹配字符 cab, 模式 的剩余部分将无法匹配;



3.12)我们使用群组来定义子表达式, 其中群组用括号() 括起来: 例如, ([+-]?)([0-9]+);然后, 你可以询问模式匹配器, 让其返回每个组的匹配,或者用 \n 引用某个群组, 其中 n 是群组号(从 \1 开始); (干货——使用群组来定义子表达式,群组用括号() 括起来)

4)正则表达式的简单用法就是测试某个特定的字符串是否与他匹配,下面展示了如何用java 来编写这段程序:

4.1)首先用 表示正则表达式的字符串构建一个 Pattern 对象

4.2)然后从这个模式获得一个 Matcher, 并调用它的 matches 方法:

Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(input);
if(mathcer.matches()) ......




4.3)这个匹配器的输入可以是任何实现了 CharSequence 接口的类对象, 例如 String, StringBuilder 和 CharBuffer;

4.4)在编译这个模式时, 你可以设置一个或多个标志,如:

Pattern pattern = Pattern.compile(patternString ,  Pattern.CASE_INSENSITIVE + Pattern.UNICODE_CASE);


4.5)下面是所支持的六种标志:

4.5.1)CASE_INSENSITIVE: 匹配字符时忽略字母的大小写, 默认情况下, 这个标志只考虑US ASCII 字符;

4.5.2)UNICODE_CASE: 当与 CASE_INSENSTITIVE 组合时, 用 Unicode 字母的大小来匹配;

4.5.3)MULTIINE: ^ 和 $ 匹配行 的开头和结尾, 而不是整个输入的开头和结尾;

4.5.4)UNIX_LINES: 在多行模式中 匹配 ^ 和 $ 时, 只有 ‘\n’ 被识别成行终止符;

4.5.5)DOTALL: 当使用这个标志时, . 符号匹配所有字符, 包括行终止符;

4.5.6)CANON_EQ: 考虑 Unicode 字符规范 的等价性;

5)如果正则表达式包含群组, 那么 Matcher 对象可以揭示群组的边界, 下面的方法: (干货——正则表达式包含群组, 那么 Matcher 对象可以揭示群组的边界)

int start(int groupIndex)
int end(int groupIndex)
将产生指定群组的开始索引和结束之后的索引;




5.1)你可以直接通过调用下面的方法抽取匹配的字符串:

String group(int groupIndex)

5.2)群组0 是这个输入, 而用于第一个实际群组的索引是1. 调用 groupCount 方法可以获得全部群组的数量;



5.3) 嵌套群组是按照前括号排序的, 例如,我们有下面的模式:

( (1?[0-9]):([0-5][0-9]) [ap]m)和下面的输出 11:59am


那么, 匹配器会报告下面 的群组:





6)通常你不希望用正则表达式来匹配全部输入,而只是想找出输入中一个或多个匹配的子字符串。

6.1)可以用 Matcher 类的 find 方法 来查找匹配内容, 如果返回 true, 再使用 start 和 end 方法来查找匹配的内容:

while(matcher.find())
{
int start=matcher.start();
int end = matcher.end();
String match = input.substring(start, end);
......
}




7) Matcher类的 replaceAll 方法将 正则表达式出现的所有地方 都用 替换字符串来替换;

7.1)如, 下面的指令将所有的数字序列都替换为 # 字符:

Pattern pattern = Pattern.compile("[0-9]+");
Mathcer matcher = pattern.matcher(input);
String output = matcher.replaceAll("#);


7.2) 替换字符串可以包含对模式中群组的引用: $n 表示替换成第n 个数组, 因此我们需要用 $ 来表示在替换文本中包含一个 $ 字符;

7.3)如果字符串包含 $ 和 \ , 但又不希望它们被解释为 群组的替换符, 那么就可以调用

matcher.replaceAll(Matcher.quoteReplacement(str));
replaceFirst() 方法将只替换的第一个出现;




7.4) 最后, Pattern类有一个 split 方法, 它可以用 正则表达式来匹配边界,从而将输入分割成字符串数组;**

7.4.1)看个荔枝: 下面的指令可以将输入 分割成标记, 其中分隔符是由可选的空白字符包围的标点符号:(干货——Pattern.split 方法参见“4.2” 中的荔枝)

Pattern pattern = Pattern.compile()"\\s*\\p{Punct}\\s*";
String[] tokens = pattern.split(input);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java