public static void main(String[] args) {
String content = "1999Java是一门面向对象的编程语言,不仅吸收了C++语言的各种优点," +
"还摒弃了C++里难以理解的多继1998承、指针等概念,因此Java语1996言具有功能强大和简单易1991用两个特征。" +
"Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方" +
"式进行复杂的编程 [1] 。n" +
"Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、" +
"多线程、动态性等特点 [2] 。Java可以编写桌面2233应用程序、Web应用程5445序、分布式系统和" +
"嵌入式系统应用程序等";
// 1. \d 表示一个任意的数字
String regStr = "(\d\d)(\d\d)";
// 2. 创建一个模式对象
Pattern pattern = Pattern.compile(regStr);
// 3. 创建匹配器
// 创建匹配器matcher 按照 正则表达式的规则,去匹配content字符串
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
// 1. group(0) 表示匹配到的子字符串
// 2. group(1) 表示匹配到的子字符串的第一组字符串
// 3. group(2) 表示匹配到的子字符串的第二组字符串
System.out.println(matcher.group(0));
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
}
}
正则表达式基本语法
| 字符 | 说明 |
|---|---|
| [xyz] | 字符集。匹配包含的任一字符。例如,"[abc]“匹配"plain"中的"a”。 |
| [^xyz] | 反向字符集。匹配未包含的任何字符。例如,"[^abc]“匹配"plain"中"p”,“l”,“i”,“n”。 |
| [a-z] | 字符范围。匹配指定范围内的任何字符。例如,"[a-z]"匹配"a"到"z"范围内的任何小写字母 |
| . | 匹配除"rn"之外的任何单个字符。若要匹配包括"rn"在内的任意字符,请使用诸如"[sS]"之类的模式。 |
| 将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如, n匹配字符 n。n 匹配换行符。序列 \\ 匹配 \ ,\( 匹配 (。 | |
| \d | 数字字符匹配。等效于 [0-9]。 |
| \D | 非数字字符匹配。等效于 [^0-9]。 |
| \w | 匹配任何字类字符,包括下划线。与"[A-Za-z0-9_]"等效。 |
| \W | 与任何非单词字符匹配。与"[^A-Za-z0-9_]"等效。 |
| {n} | n 是非负整数。正好匹配 n 次。例如,"o{2}"与"Bob"中的"o"不匹配,但与"food"中的两个"o"匹配。 |
| {n,} | n 是非负整数。至少匹配 n 次。例如,"o{2,}“不匹配"Bob"中的"o”,而匹配"foooood"中的所有 o。"o{1,}“等效于"o+”。"o{0,}“等效于"o*”。 |
| {n,m} | m 和 n 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次。例如,"o{1,3}"匹配"fooooood"中的头三个 o。‘o{0,1}’ 等效于 ‘o?’。注意:您不能将空格插入逗号和数字之间。 |
| * | 零次或多次匹配前面的字符或子表达式。例如,zo* 匹配"z"和"zoo"。* 等效于 {0,}。 |
| ? | 零次或一次匹配前面的字符或子表达式。例如,"do(es)?“匹配"do"或"does"中的"do”。? 等效于 {0,1}。 |
| x|y | 匹配 x 或 y。例如,'z |
| ? | 当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。例如,在字符串"oooo"中,"o+?“只匹配单个"o”,而"o+“匹配所有"o”。 |
| f | 换页符匹配。等效于 x0c 和 cL。 |
| n | 换行符匹配。等效于 x0a 和 cJ。 |
| r | 匹配一个回车符。等效于 x0d 和 cM。 |
| s | 匹配任何空白字符,包括空格、制表符、换页符等。与 [ fnrtv] 等效。 |
| S | 匹配任何非空白字符。与 [^ fnrtv] 等效。 |
| t | 制表符匹配。与 x09 和 cI 等效。 |
| v | 垂直制表符匹配。与 x0b 和 cK 等效。 |
| b | 匹配一个字边界,即字与空格间的位置。例如,“erb"匹配"never"中的"er”,但不匹配"verb"中的"er"。 |
| B | 非字边界匹配。“erB"匹配"verb"中的"er”,但不匹配"never"中的"er"。 |
| + | 一次或多次匹配前面的字符或子表达式。例如,"zo+"与"zo"和"zoo"匹配,但与"z"不匹配。+ 等效于 {1,}。 |
| (pattern) | 匹配 pattern 并捕获该匹配的子表达式。可以使用 $0…$9 属性从结果"匹配"集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用"(“或者”)"。 |
| (?:pattern) | 匹配 pattern 但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用"or"字符 (|) 组合模式部件的情况很有用。例如,'industr(?:y|ies) 是比 ‘industry|industries’ 更经济的表达式。 |
| (?=pattern) | 执行正向预测先行搜索的子表达式,该表达式匹配处于匹配 pattern 的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,‘Windows (?=95|98|NT|2000)’ 匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。 |
| (?!pattern) | 执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,‘Windows (?!95|98|NT|2000)’ 匹配"Windows 3.1"中的 “Windows”,但不匹配"Windows 2000"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。 |
public static void main(String[] args) {
String content = "a11c8";
// Pattern pattern = Pattern.compile("[a-z]"); // 匹配a-z之间的任意字符
// Pattern pattern = Pattern.compile("[^a-z]"); // 匹配不是a-z之间的任意字符
// Pattern pattern = Pattern.compile("[A-Z]"); // 匹配A-Z之间的任意字符
// Pattern pattern = Pattern.compile("[0-9]"); // 匹配0-9之间的任意字符
Pattern pattern = Pattern.compile("[^0-9]"); // 匹配不是0-9之间的任意字符
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
}
@Test
public void test01 () {
String content = "a11c8abcABCaBc";
// Pattern pattern = Pattern.compile("abc"); // 匹配abc
// Pattern pattern = Pattern.compile("(?i)abc"); // 表示abc不区分大小写的abc
// Pattern pattern = Pattern.compile("a(?i)bc"); // 表示bc不区分大小写的abc
Pattern pattern = Pattern.compile("a((?i)b)c"); // 表示b不区分大小写的abc
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
}
@Test
public void test02 () {
String content = "a11c8abcABCaBc";
// 当穿件Pattern对象时,指定Pattern.CASE_INSENSITIVE 表示匹配是不区分字母大小写
Pattern pattern = Pattern.compile("abc", Pattern.CASE_INSENSITIVE); // 匹配abc
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
}
@Test
public void test03 () {
String content = "a11c8abcABCaBc";
// Pattern pattern = Pattern.compile("[abcd]"); // 匹配abcd中任意字符
Pattern pattern = Pattern.compile("[^abcd]"); // 匹配不是abcd中任意字符
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
}
@Test
public void test04 () {
String content = "a11c8abcABC——_ a Bc";
Pattern pattern1 = Pattern.compile("\d"); // 匹配数字
Pattern pattern2 = Pattern.compile("\D"); // 匹配非数字
Pattern pattern3 = Pattern.compile("\w"); // 匹配英文字符、数组和下划线[a-zA-Z0-9_]
Pattern pattern4 = Pattern.compile("\W"); // 匹配非文字符、数组和下划线
Pattern pattern5 = Pattern.compile("\s"); // 匹配任何空白字符(空格 制表符 等)
Pattern pattern6 = Pattern.compile("\S"); // 匹配非任何空白字符(空格 制表符 等)
Pattern pattern7= Pattern.compile("."); // 匹配除n r 之外的所有字符
Matcher matcher = pattern7.matcher(content);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
}
三个常用类△
Pattern
pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
public static void main(String[] args) {
String content = "hello java abc123";
String regExp = "hello.*";
// 整体与正则表达式进行匹配:比较简洁
// 返回 true 或 false
boolean matches = Pattern.matches(regExp, content);
System.out.println(matches);
}
Matcher
Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
public static void main(String[] args) {
String content = "hello java, hello world";
String regExp = "hello";
Pattern pattern = Pattern.compile(regExp);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("==================");
System.out.println(matcher.start());
System.out.println(matcher.end());
System.out.println(content.substring(matcher.start(), matcher.end()));
}
System.out.println(matcher.matches()); // 整体匹配,false
// 若content中有java 替换成 JavaStudy
regExp = "java";
pattern = Pattern.compile(regExp);
matcher = pattern.matcher(content);
// 返回的字符串才是替换后的字符串,原来的content不回变换
String all = matcher.replaceAll("JavaStudy");
System.out.println("====返回的替换结果======= " + all);
System.out.println("====原来的信息不回改变======= " + content);
}
PatternSyntaxException
PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
分组、捕获、反向作用△ 分组和捕获 分组是用圆括号“()”括起来的正则表达式,匹配出的内容就表示一个分组。分组有一个例外的情况,分组也可以不使用圆括号,而是使用 | 元字符来表示分组,| 的两侧是两个分组,例如, exp1 | exp2 表示两个分组,在严格意义闪给,不认为由 | 构成的正则表达式是分组。
分组和捕获在正则表达式中有着密切的联系,一般情况下,分组即捕获,都用小括号完成:
(exp) :分组,并捕获该分组匹配到的文本(?:exp) :分组,但不捕获该分组匹配到的文本
什么是捕获呢?使用小括号指定一个子表达式后,子表达式匹配的文本(即匹配的内容)可以在其他子表达式中重复使用。
(exp) :把括号内的正则作为一个分组,系统自动分配组号,可以通过分组号引用该分组;(?Pexp) :定义一个命名分组,分组的正则是exp,系统为该分组分配分组号,可以通过分组名或分组号引用该分组;(?:exp) :定义一个不捕获分组,该分组只在当前位置匹配文本,在该分组之后,无法引用该分组,因为该分组没有分组名,没有分组号,也不会占用分组编号;
在正则表达式中,分组编号是自动进行的。当使用圆括号表示分组时,从正则表达式的左边开始看,看到的第一个左括号 “(” 表示第一个分组,第二个 “(” 表示第二个分组,依次类推,需要注意的是,有一个隐含的全局分组(分组编号是0),就是整个正则表达式。默认情况下,正则表达式为每个分组自动分配一个组号,规则是:组号从1开始,从左向右,组号依次加1(base+1),例如,第一个分组的组号为1,第二个分组的组号为2,以此类推。
反向引用 圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用\分组号,外部反向引用$分组号。
元字符△ 限定符public static void main(String[] args) {
String content = "xxxaaswxyab12cabcabcqwmabcabcabcexwmabcrx1237894aaa564";
String regExp = "a{3}"; // 匹配长度为3的a
String regExp1 = "\d{3}"; // 匹配长度为3的任意数字
// 贪婪匹配,尽可能匹配多的aaa 不会 匹配aa 而是 匹配aaa
String regExp2 = "a{2,3}"; // 匹配长度为2到3的a
String regExp3 = "[abcd]{2,5}"; // 匹配长度为2到5的由abcd其中任意字符组成的字符串
String regExp4 = "\d{3,6}"; // 匹配长度为2到6的的数字
Pattern pattern = Pattern.compile(regExp4);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
}
@Test
public void test01() {
String content = "xxxaaswxyab12cabcabcqa1wmabcabcabcexwmabcrx1237894aaa564";
String regExp1 = "(aa)+"; // 匹配aa到多个aa
String regExp2 = "aa+"; // 匹配aa到多个a
String regExp3 = "a*"; // 匹配0-n个a
String regExp4 = "a?"; // 匹配0-1个a
String regExp5 = "a1?"; // 匹配a或a1
Pattern pattern = Pattern.compile(regExp5);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
}
选择匹配符
String content = "xxxaaswxyqwexwrx1237894564";
String regExp = "wxy|xwr|aa"; // wxy 或 xwr 或aa
Pattern pattern = Pattern.compile(regExp);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
定位符
@Test
public void display01() {
String content = "123abc";
String content1 = "123-abc";
String regExp1 = "^[0-9]+[a-z]*";
String regExp2 = "^[0-9]+[a-z]+$";
String regExp3 = "^[0-9]+\-[a-z]+$";
Pattern pattern = Pattern.compile(regExp3);
Matcher matcher = pattern.matcher(content1);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
}
@Test
public void display02() {
String content = "does invest";
// 匹配便捷的es[边界是指:被匹配的字符串最后,也可以是空格的字符串的后面]
String regExp1 = "es\b";
String regExp2 = "es\B";
Pattern pattern = Pattern.compile(regExp2);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
}
分组和反向引用符
@Test
public void display01() {
String content = "123abc s7789 nn1189wxy";
String regExp1 = "(\d\d)(\d\d)"; // 非命名分组
Pattern pattern = Pattern.compile(regExp1);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
// 0 表示匹配到的所有字符串
// 1 表示匹配到的所有字符串的第一组子字符串
// 2 表示匹配到的所有字符串的第二组子字符串
System.out.println(matcher.group(0));
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
}
}
@Test
public void display02() {
String content = "123abc s7789 nn118956wxy";
String regExp1 = "(?\d\d)(?\d\d)(\d\d)"; // 命名分组+非命名分组
Pattern pattern = Pattern.compile(regExp1);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
// 0 表示匹配到的所有字符串
// one 表示匹配到的所有字符串的name=one的子字符串
// two 表示匹配到的所有字符串的name=two的子字符串
System.out.println(matcher.group(0));
System.out.println(matcher.group("one"));
System.out.println(matcher.group("two"));
System.out.println(matcher.group(3));
}
}
@Test
public void display03() {
String content = "123abc s7789 nn118aaaaa956wxy";
String regExp1 = "a{3,5}?"; // 非贪婪匹配 返回aaa
String regExp2 = "a{3,5}"; // 贪婪匹配 返回aaaaa
Pattern pattern = Pattern.compile(regExp1);
Matcher matcher = pattern.matcher (content);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
}
特殊字符
字符匹配符
字符串中使用正则表达式
public static void main(String[] args) {
// 1. 替换
String content = "java web web web ajax linux";
content = content.replaceAll("web|ajax|linux", "java");
System.out.println(content); // java java java java java java
// 2. 验证
String tel = "13688889999";
System.out.println(tel.matches("1(38|39|36)\d{8}")); // true
System.out.println(tel.matches("13[389]\d{8}")); // true
// 3. 分割
String words = "java ajax#web-linux9springboot~regis mysql";
String[] split = words.split("[#~-]|\d+|\s+");
for (String s : split) {
System.out.println(s);
}
}
应用实例
案例一
@Test
public void vertify01() {
// 验证汉字
String context = "卷起来";
String regExp = "^[u0391-uffe5]+$";
// 验证邮编格式
String context1 = "123456";
String regExp1 = "^[0-9]\d{5}+$";
// 验证qq格式
String context2 = "1710050555";
String regExp2 = "^[1-9]\d{4,9}+$";
// 验证tel格式
String context3 = "15566668888";
String regExp3 = "^1[3|4|5|8]\d{9}+$";
// 验证url格式
String context4 = "https://www.runoob.com/java/java-regular-expressions.html";
String regExp4 = "^((http|https)://)([\w-]+\.)+[\w-]+(\/[\w-?=&/%.]*)?$";
Pattern pattern = Pattern.compile(regExp4);
Matcher matcher = pattern.matcher(context4);
if (matcher.find()) {
System.out.println(matcher.group(0));
System.out.println("格式正确!");
} else {
System.out.println("格式错误!");
}
}
案例二
public static void main(String[] args) {
String content = "我....我要....学学学学学....JJava";
// 1. 去掉所有的.
Pattern pattern = Pattern.compile("\.");
Matcher matcher = pattern.matcher(content);
content = matcher.replaceAll("");
// 2. 去掉重复字
pattern = Pattern.compile("(.)\1+");
matcher = pattern.matcher(content);
// 使用反向引用$1来替换匹配的内容
content = matcher.replaceAll("$1");
System.out.println(content);
}
@Test
public void test01() { // 简洁写法
String content = "我....我要....学学学学学....JJava";
content = Pattern.compile("\.").matcher(content).replaceAll("");
content = Pattern.compile("(.)\1+").matcher(content).replaceAll("$1");
System.out.println(content);
}
正则表达式大全
一、校验数字的表达式
1 数字:^[0-9]*$
2 n位的数字:^d{n}$
3 至少n位的数字:^d{n,}$
4 m-n位的数字:^d{m,n}$
5 零和非零开头的数字:^(0|[1-9][0-9]*)$
6 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
7 带1-2位小数的正数或负数:^(-)?d+(.d{1,2})?$
8 正数、负数、和小数:^(-|+)?d+(.d+)?$
9 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
10 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
11 非零的正整数:^[1-9]d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^+?[1-9][0-9]*$
12 非零的负整数:^-[1-9][]0-9"*$ 或 ^-[1-9]d*$
13 非负整数:^d+$ 或 ^[1-9]d*|0$
14 非正整数:^-[1-9]d*|0$ 或 ^((-d+)|(0+))$
15 非负浮点数:^d+(.d+)?$ 或 ^[1-9]d*.d*|0.d*[1-9]d*|0?.0+|0$
16 非正浮点数:^((-d+(.d+)?)|(0+(.0+)?))$ 或 ^(-([1-9]d*.d*|0.d*[1-9]d*))|0?.0+|0$
17 正浮点数:^[1-9]d*.d*|0.d*[1-9]d*$ 或 ^(([0-9]+.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*.[0-9]+)|([0-9]*[1-9][0-9]*))$
18 负浮点数:^-([1-9]d*.d*|0.d*[1-9]d*)$ 或 ^(-(([0-9]+.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*.[0-9]+)|([0-9]*[1-9][0-9]*)))$
19 浮点数:^(-?d+)(.d+)?$ 或 ^-?([1-9]d*.d*|0.d*[1-9]d*|0?.0+|0)$
二、校验字符的表达式
1 汉字:^[u4e00-u9fa5]{0,}$
2 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
3 长度为3-20的所有字符:^.{3,20}$
4 由26个英文字母组成的字符串:^[A-Za-z]+$
5 由26个大写英文字母组成的字符串:^[A-Z]+$
6 由26个小写英文字母组成的字符串:^[a-z]+$
7 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
8 由数字、26个英文字母或者下划线组成的字符串:^w+$ 或 ^w{3,20}$
9 中文、英文、数字包括下划线:^[u4E00-u9FA5A-Za-z0-9_]+$
10 中文、英文、数字但不包括下划线等符号:^[u4E00-u9FA5A-Za-z0-9]+$ 或 ^[u4E00-u9FA5A-Za-z0-9]{2,20}$
11 可以输入含有^%&',;=?$"等字符:[^%&',;=?$x22]+
12 禁止输入含有~的字符:[^~x22]+
三、特殊需求表达式
1 Email地址:^w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$
2 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
3 InternetURL:[a-zA-z]+://[^s]* 或 ^https://([w-]+.)+[w-]+(/[w-./?%&=]*)?$
4 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])d{8}$
5 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^((d{3,4}-)|d{3.4}-)?d{7,8}$
6 国内电话号码(0511-4405222、021-87888822):d{3}-d{8}|d{4}-d{7}
7 身份证号:
15或18位身份证:^d{15}|d{18}$
15位身份证:^[1-9]d{7}((0d)|(1[0-2]))(([0|1|2]d)|3[0-1])d{3}$
18位身份证:^[1-9]d{5}[1-9]d{3}((0d)|(1[0-2]))(([0|1|2]d)|3[0-1])d{4}$
8 短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$ 或 ^d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
9 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
10 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]w{5,17}$
11 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
12 日期格式:^d{4}-d{1,2}-d{1,2}
13 一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
14 一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
15 钱的输入格式:
16 1.有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
17 2.这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$
18 3.一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$
19 4.这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$
20 5.必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^[0-9]+(.[0-9]{2})?$
21 6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$
22 7.这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
23 8.1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
24 备注:这就是最终结果了,别忘了"+"可以用"*"替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里
25 xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\.[x|X][m|M][l|L]$
26 中文字符的正则表达式:[u4e00-u9fa5]
27 双字节字符:[^x00-xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
28 空白行的正则表达式:ns*r (可以用来删除空白行)
29 HTML标记的正则表达式:<(S*?)[^>]*>.*?|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
30 首尾空白字符的正则表达式:^s*|s*$或(^s*)|(s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
31 腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
32 中国邮政编码:[1-9]d{5}(?!d) (中国邮政编码为6位数字)
33 IP地址:d+.d+.d+.d+ (提取IP地址时有用)



