软件构造的实验3用到了正则表达式,所以我到网上学习了相关的知识。
Java 正则表达式
正则表达式定义了字符串的模式。
正则表达式可以用来搜索、编辑或处理文本。
正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。
最简单的正则表达式是字符串,例如"Hello World"可以直接被正则表达式识别接受。
正则表达式语法
正则表达式的具体语法可以参考Java 正则表达式 | 菜鸟教程 (runoob.com)
下面仅强调个人认为最重要最基础的内容:
1."\":
在其他语言中,\\ 表示:我想要在正则表达式中插入一个普通的(字面上的)反斜杠,请不要给它任何特殊的意义。
在 Java 中,\\ 表示:我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。
所以,在其他的语言中(如 Perl),一个反斜杠 \ 就足以具有转义的作用,而在 Java 中正则表达式中则需要有两个反斜杠才能被解析为其他语言中的转义作用。也可以简单的理解在 Java 的正则表达式中,两个 \\ 代表其他语言中的一个 \,这也就是为什么表示一位数字的正则表达式是 \\d,而表示一个普通的反斜杠是 \\。
2."*"、"+"、"?":
"*"表示零次或多次匹配前面的字符或子表达式。例如,zo* 匹配"z"和"zoo"。* 等效于 {0,}
"+"表示一次或多次匹配前面的字符或子表达式。例如,"zo+"与"zo"和"zoo"匹配,但与"z"不匹配。+ 等效于 {1,}。
"?"表示零次或一次匹配前面的字符或子表达式。例如,"do(es)?"匹配"do"或"does"中的"do"。? 等效于 {0,1}。
3.{n,m}"与"{n}":
m,n为非负整数,m>n.
"{n}"表示正好匹配 n 次。例如,"o{2}"与"Bob"中的"o"不匹配,但与"food"中的两个"o"匹配。
"{n,m}"表示n 是非负整数。正好匹配 n 次。例如,"o{2}"与"Bob"中的"o"不匹配,但与"food"中的两个"o"匹配。
"{n,}"表示至少匹配 n 次。例如,"o{2,}"不匹配"Bob"中的"o",而匹配"foooood"中的所有 o。"o{1,}"等效于"o+"。"o{0,}"等效于"o*"。
4."x|y":
表示匹配 x 或 y。例如,'z|food' 匹配"z"或"food"。'(z|f)ood' 匹配"zood"或"food"。
5."[a-z]"与"[^a-z]":
"[a-z]"表示字符范围。匹配指定范围内的任何字符。例如,"[a-z]"匹配"a"到"z"范围内的任何小写字母。
"[^a-z]"表示反向范围字符。匹配不在指定的范围内的任何字符。例如,"[^a-z]"匹配任何不在"a"到"z"范围内的任何字符。
Java中常用的处理正则表达式的三个类
- Pattern 类:
pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
- Matcher 类:
Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
- PatternSyntaxException:
PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
-
三个类都包含在java.util.regex 包中
-
具体操作亦可参考Java 正则表达式 | 菜鸟教程 (runoob.com)
捕获组
捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。
例如,正则表达式 (dog) 创建了单一分组,组里包含"d","o",和"g"。
捕获组是通过从左至右计算其开括号来编号。例如,在表达式((A)(B(C))),有四个这样的组:
- ((A)(B(C)))
- (A)
- (B(C))
- (C)
可以通过调用 matcher 对象的 groupCount 方法来查看表达式有多少个分组。groupCount 方法返回一个 int 值,表示matcher对象当前有多个捕获组。
还有一个特殊的组(group(0)),它总是代表整个表达式。该组不包括在 groupCount 的返回值中。
实例操作
现有要求:
number:大于 10000 的数字按科学记数法表示(例如1.9885e30 表示1.9885 ∗ 10!",但 e 之前数字的整数部分必须在 1 到 9 的范围内,e 之后的数字只能是大于 3 的正整数), 小于 10000 的数字直接给出(例如 5912,103.193), 不能用科学计数法。小数点位数不限制。数字为非负数。
设计的正则表达式为:
REGEX = "0*(" +
"(10000)|([0-9]{1,4})|([0-9]{1,4}\\.[0-9]+)|" + //小于10000
"(" + //大于10000,科学计数法
"([0-9])|([0-9]\\.[0-9]+)" + //e之前的数字
"e" +
"((0*[4-9])|(0*[1-9][0-9]+))" + //e之后的数字
")" +
")";
采用一下测试用例进行测试:
String test1 = "s";
String test2 = "2x2";
String test3 = "1";
String test4 = "1.2";
String test5 = "145.2345";
String test6 = "00010000";
String test7 = "0006.546";
String test8 = "12345";
String test9 = "2.695e10";
String test10 = "21e32";
String test11 = "2e2";
String test12 = "6.e21";
String test13 = "3e6e8";
String test14 = "-65";
String test15 = "6 5";
String test16 = "";
String test17 = " ";
测试结果: