正则练习题

一、正则表达式(Regular Expression)
正则表达式就是一个验证字符串格式是否满足要求的字符串。 使用一个字符串匹配一组字符串,这个字符串就是正则表达式(模式)

(1)字符类:

元符集 解释
a 字符a
[abc] 匹配a、b、c
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[ ^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[ ^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
(2)预定义字符类:

预定义字符类 解释
. 任意字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\w 单词字符[a-zA-Z_0-9]
^ 行开头
$ 行结尾
X? 一次或0次
X* 0次或多次(包括1次)
X+ 一次或多次
X{n} 恰好n次
X{n,} 至少n次
X{n,m} 至少n次,不超过m次
(3)匹配电话号码:

//匹配电话号码
String phone = “18637866964”;
String reg = “^1[3,5,7,8,9]\d{9}$”;
System.out.println(phone.matches(reg));
原理:

String 中的matches()方法,用来进行正则表达式的验证,匹配返回 true,否则返回 false。

String中的源码:

public boolean matches(String regex) {
    return Pattern.matches(regex, this);
}

在String 的matches()方法中使用了 Pattern 的静态方法 matches()方法进行正则表达式的验证。Pattern的matches()方法的源码:

public static boolean matches(String regex, CharSequence input) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
return m.matches();
}
从源码中可以看出:正则表达式的一般使用步骤:

正则表达式首先首先被编译为 Pattern (模式)对象;
根据 Pattern 对象的 matcher() 方法创建 Matcher(匹配器)对象,该方法以待验证的输入字符为参数;
使用Matcher对象的matches()方法进行正则表达式验证,并返回结果;
如果正则表达式只使用一次,也可以写成如下形式:

boolean b = Matcher.matches(reg,input);
(4)正则表达式的其他应用:

正则表达式除了可以进行字符串的匹配验证,还可以进行拆分字符串、获取字符串的子串、字符串替换:

1)拆分字符串:

String test_1 = “my name is suxing”;
//根据空格拆分字符串,“ +”:匹配一个或多个空格。
String [] words = test_1.split(" +");
for(String s:words){
System.out.println(s);
}
//根据空格或逗号拆分字符串,“[ ,]”:匹配一个空格或一个逗号
String test_2 = “my name is zhangsan,wlecome to beijing”;
String [] words_1 = test_2.split("[ ,]");
for(String s:words_1){
System.out.println(s);
}
2)获取子串:

//获取字符串中的java、Java、JAVA
String test_1 = “java 是世界上最好的语言,Java天下第一,我爱JAVA”;
String reg = “[jJ]ava|JAVA”;
Pattern pattern = Pattern.compile(reg);
Matcher matcher = pattern.matcher(test_1);

while (matcher.find()){
System.out.println(matcher.group());
}
使用 Matcher 对象的find() 方法查询是否存在满足正则表达式的字符串,如果有,使用group() 方法输出。

3)替换:

//把字符串中的java、Java、JAVA全部替换成PHP
String test_1 = “java 是世界上最好的语言,Java天下第一,我爱JAVA”;
String reg = “[jJ]ava|JAVA”;
String test_2 = test_1.replaceAll(reg,“PHP”);
System.out.println(test_2);
4)统计字符串出现的次数:

package com.qianfeng.kaoti01;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test02 {
public static void main(String[] args) {
int num = 0;
String str= “I wish you become better and better”;
String reg = “[e]”;
Pattern pattern = Pattern.compile(reg);
Matcher matcher = pattern.matcher(str);

    while (matcher.find()){
        num++;
    }
    System.out.println("共"+num+"个e");
}

}
(5)练习题:

1、利用正则表达式,把 “我…我我…喜欢欢欢…编编程程程…” ,转换成 “我喜欢编程” ;

String test_1 = “我…我我…喜欢欢欢…编编程程程…”;
String test_2 = test_1.replace(".","");
String test_3 = test_2.replaceAll("(.)\1+","$1");
System.out.println(test_3);
“\1"表示引用前面的一组表达式即 “(.)”,”$1” 表示 “\1” ;

2、利用正则表达式,把 “我…喜欢喜欢…编程编程编程…” ,转换成 “我喜欢编程” ;

String test_1 = “我…喜欢喜欢…编程编程编程…”;
String test_2 = test_1.replace(".","");
String test_3 = test_2.replaceAll("(.)(.)(\1\2)+","$1$2");
System.out.println(test_3);

在做项目的过程中,使用正则表达式来匹配一段文本中的特定种类字符,是比较常用的一种方式,下面是对常用的正则匹配做了一个归纳整理。

1、匹配中文:[\u4e00-\u9fa5]

2、英文字母:[a-zA-Z]

3、数字:[0-9]

4、匹配中文,英文字母和数字及下划线:1+$
同时判断输入长度:
[\u4e00-\u9fa5_a-zA-Z0-9_]{4,10}

5、
(?!)  不能以_开头
(?!.*?
$)  不能以_结尾
[a-zA-Z0-9_\u4e00-\u9fa5]+  至少一个汉字、数字、字母、下划线
$  与字符串结束的地方匹配

6、只含有汉字、数字、字母、下划线,下划线位置不限:
2+$

7、由数字、26个英文字母或者下划线组成的字符串
^\w+$

8、2~4个汉字
3{2,4}$”;

9、最长不得超过7个汉字,或14个字节(数字,字母和下划线)正则表达式
4{1,7}KaTeX parse error: Undefined control sequence: \dA at position 4: |^[\̲d̲A̲-Za-z_]{1,14}

10、匹配双字节字符(包括汉字在内):[^x00-xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

11、匹配空白行的正则表达式:ns*r
评注:可以用来删除空白行

12、匹配HTML标记的正则表达式:<(S*?)[^>]>.?|<.*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力

13、匹配首尾空白字符的正则表达式:^s*|s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式

14、匹配Email地址的正则表达式:5[\w.-][a-zA-Z0-9]@[a-zA-Z0-9][\w.-][a-zA-Z0-9].[a-zA-Z][a-zA-Z.]*[a-zA-Z]$

评注:表单验证时很实用

15、手机号:^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\d{8}$

16、身份证:(^\d{15}KaTeX parse error: Undefined control sequence: \d at position 5: )|(^\̲d̲{17}([0-9]|X|x))

17、匹配网址URL的正则表达式:[a-zA-z]+://[^s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求

18、匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):6[a-zA-Z0-9_]{4,15}$
评注:表单验证时很实用

19、匹配国内电话号码:d{3}-d{8}|d{4}-d{7}
评注:匹配形式如 0511-4405222 或 021-87888822

20、匹配腾讯QQ号:[1-9][0-9]{4,}
评注:腾讯QQ号从10000开始

21、匹配中国邮政编码:[1-9]d{5}(?!d)
评注:中国邮政编码为6位数字

22、匹配身份证:d{15}|d{18}
评注:中国的身份证为15位或18位

23、匹配ip地址:d+.d+.d+.d+
评注:提取ip地址时有用

24、匹配特定数字:
7d*     / / 匹 配 正 整 数 − [ 1 − 9 ] d ∗     //匹配正整数 ^-[1-9]d*   //[19]d   //匹配负整数
^-?[1-9]d*     / / 匹 配 整 数 [ 1 − 9 ] d ∗ ∣ 0    //匹配整数 ^[1-9]d*|0   //[19]d0  //匹配非负整数(正整数 + 0)
^-[1-9]d*|0     / / 匹 配 非 正 整 数 ( 负 整 数 + 0 ) [ 1 − 9 ] d ∗ . d ∗ ∣ 0. d ∗ [ 1 − 9 ] d ∗    //匹配非正整数(负整数 + 0) ^[1-9]d*.d*|0.d*[1-9]d*   //+0[19]d.d0.d[19]d   //匹配正浮点数
^-([1-9]d*.d*|0.d*[1-9]d*)   / / 匹 配 负 浮 点 数 − ? ( [ 1 − 9 ] d ∗ . d ∗ ∣ 0. d ∗ [ 1 − 9 ] d ∗ ∣ 0 ? . 0 + ∣ 0 )   //匹配负浮点数 ^-?([1-9]d*.d*|0.d*[1-9]d*|0?.0+|0)  //?([19]d.d0.d[19]d0?.0+0)  //匹配浮点数
8d*.d*|0.d*[1-9]d*|0?.0+|0     / / 匹 配 非 负 浮 点 数 ( 正 浮 点 数 + 0 ) ( − ( [ 1 − 9 ] d ∗ . d ∗ ∣ 0. d ∗ [ 1 − 9 ] d ∗ ) ) ∣ 0 ? . 0 + ∣ 0    //匹配非负浮点数(正浮点数 + 0) ^(-([1-9]d*.d*|0.d*[1-9]d*))|0?.0+|0   //+0(([19]d.d0.d[19]d))0?.0+0  //匹配非正浮点数(负浮点数 + 0)
评注:处理大量数据时有用,具体应用时注意修正

25、匹配特定字符串:
9+     / / 匹 配 由 26 个 英 文 字 母 组 成 的 字 符 串 [ A − Z ] +   //匹配由26个英文字母组成的字符串 ^[A-Z]+   //26[AZ]+  //匹配由26个英文字母的大写组成的字符串
10+     / / 匹 配 由 26 个 英 文 字 母 的 小 写 组 成 的 字 符 串 [ A − Z a − z 0 − 9 ] +   //匹配由26个英文字母的小写组成的字符串 ^[A-Za-z0-9]+   //26[AZaz09]+  //匹配由数字和26个英文字母组成的字符串
^w+$  //匹配由数字、26个英文字母或者下划线组成的字符串

26、
在使用RegularExpressionValidator验证控件时的验证功能及其验证表达式介绍如下:
只能输入数字:“11 ” 只 能 输 入 n 位 的 数 字 : “ d n ” 只能输入n位的数字:“^d{n} ndn
只能输入至少n位数字:“^d{n,} ” 只 能 输 入 m − n 位 的 数 字 : “ d m , n ” 只能输入m-n位的数字:“^d{m,n} mndm,n
只能输入零和非零开头的数字:“^(0|[1-9][0-9]
) ” 只 能 输 入 有 两 位 小 数 的 正 实 数 : “ [ 0 − 9 ] + ( . [ 0 − 9 ] 2 ) ? ” 只能输入有两位小数的正实数:“^[0-9]+(.[0-9]{2})? [09]+(.[09]2)?
只能输入有1-3位小数的正实数:“12+(.[0-9]{1,3})? ” 只 能 输 入 非 零 的 正 整 数 : “ + ? [ 1 − 9 ] [ 0 − 9 ] ∗ ” 只能输入非零的正整数:“^+?[1-9][0-9]* +?[19][09]
只能输入非零的负整数:“^-[1-9][0-9] ” 只 能 输 入 长 度 为 3 的 字 符 : “ . 3 ” 只能输入长度为3的字符:“^.{3} 3.3
只能输入由26个英文字母组成的字符串:“13+ ” 只 能 输 入 由 26 个 大 写 英 文 字 母 组 成 的 字 符 串 : “ [ A − Z ] + ” 只能输入由26个大写英文字母组成的字符串:“^[A-Z]+ 26[AZ]+
只能输入由26个小写英文字母组成的字符串:“14+ ” 只 能 输 入 由 数 字 和 26 个 英 文 字 母 组 成 的 字 符 串 : “ [ A − Z a − z 0 − 9 ] + ” 只能输入由数字和26个英文字母组成的字符串:“^[A-Za-z0-9]+ 26[AZaz09]+
只能输入由数字、26个英文字母或者下划线组成的字符串:“^w+ ” 验 证 用 户 密 码 : “ [ a − z A − Z ] w 5 , 17 ” 验证用户密码:“^[a-zA-Z]w{5,17} :[azAZ]w5,17”正确格式为:以字母开头,长度在6-18之间,
只能包含字符、数字和下划线。
验证是否含有^%&’,;=?KaTeX parse error: Expected group after '^' at position 8: "等字符:“[^̲%&',;=?x22]+”
只能输入汉字:“15,{0,} ” 验 证 E m a i l 地 址 : “ w + [ − + . ] w + ) ∗ @ w + ( [ − . ] w + ) ∗ . w + ( [ − . ] w + ) ∗ ” 验证Email地址:“^w+[-+.]w+)*@w+([-.]w+)*.w+([-.]w+)* Emailw+[+.]w+)@w+([.]w+).w+([.]w+)
验证InternetURL:“^http://([w-]+.)+[w-]+(/[w-./?%&=]
)? ” 验 证 身 份 证 号 ( 15 位 或 18 位 数 字 ) : “ d 15 ∣ d 18 ” 验证身份证号(15位或18位数字):“^d{15}|d{}18 1518d15d18
验证一年的12个月:“^(0?[1-9]|1[0-2]) ” 正 确 格 式 为 : “ 01 ” − “ 09 ” 和 “ 1 ” “ 12 ” 验 证 一 个 月 的 31 天 : “ ( ( 0 ? [ 1 − 9 ] ) ∣ ( ( 1 ∣ 2 ) [ 0 − 9 ] ) ∣ 30 ∣ 31 ) ”正确格式为:“01”-“09”和“1”“12” 验证一个月的31天:“^((0?[1-9])|((1|2)[0-9])|30|31) 010911231((0?[19])((12)[09])3031)
正确格式为:“01”“09”和“1”“31”。
匹配中文字符的正则表达式: [u4e00-u9fa5]
匹配双字节字符(包括汉字在内):[^x00-xff]
匹配空行的正则表达式:n[s| ]r
匹配HTML标记的正则表达式:/<(.
)>.|<(.) />/
匹配首尾空格的正则表达式:(^s*)|(s*$)
匹配Email地址的正则表达式:w+([-+.]w+)@w+([-.]w+).w+([-.]w+)*
匹配网址URL的正则表达式:http://([w-]+.)+[w-]+(/[w- ./?%&=]*)?

1.如何从字符串中提取数字?

使用正则表达式的一个常见问题是将所有数字提取到整数数组中。

在Java中,\d表示一个数字范围(0-9)。尽可能使用预定义的类将使代码更易于阅读,并消除格式错误的字符类引入的错误。有关更多详细信息,请参阅预定义字符类。请注意,第一个反斜杠\在\d。如果在字符串文字中使用转义构造,则必须在反斜杠前面加上另一个反斜杠,以便编译字符串。这就是我们需要使用的原因\d。

List numbers = new LinkedList();
Pattern p = Pattern.compile("\d+");
Matcher m = p.matcher(str);
while (m.find()) {
numbers.add(Integer.parseInt(m.group()));
}
2.如何按换行符拆分Java String?

根据您正在使用的操作系统,至少有三种不同的输入换行符的方法。

\ r表示CR(回车),用于Unix
\ n表示在Mac OS中使用的LF(换行)
\ r \ n表示在Windows中使用的CR + LF
因此,用新线分割字符串最直接的方法是

String lines[] = String.split("\r?\n");
但如果你不想要空行,你可以使用,这也是我最喜欢的方式:

String.split("[\r\n]+")
一种更加健壮的方式,实际上与系统无关,如下所示。但请记住,如果并排放置两个换行符,您仍然会得到空行。

String.split(System.getProperty(“line.separator”));

  1. Pattern.compile()的重要性

必须首先将指定为字符串的正则表达式编译为Pattern类的实例。图案。compile()方法是创建对象实例的唯一方法。因此,典型的调用序列

Pattern p = Pattern.compile(“a*b”);
Matcher matcher = p.matcher(“aaaaab”);
assert matcher.matches() == true;
基本上,模式。compile()用于将正则表达式转换为有限状态机(请参阅编译器:原理,技术和工具(第2版))。但参与比赛的所有州都在比赛中。通过这种方式,可以重用Pattern p。许多匹配者可以共享相同的模式。

Matcher anotherMatcher = p.matcher(“aab”);
assert anotherMatcher.matches() == true;
模式。matches()方法被定义为只使用正则表达式时的便利。此方法仍然使用compile()隐式获取Pattern的实例,并匹配字符串。因此,

boolean b = Pattern.matches(“a*b”, “aaaaab”);
等同于上面的第一个代码,但是对于重复匹配,它效率较低,因为它不允许重用已编译的模式。

4.如何转义正则表达式的文本?

通常,正则表达式使用“\”来转义构造,但是在反斜杠之前用另一个反斜杠来编译Java字符串是很痛苦的。用户可以通过另一种方式将字符串文字传递给模式,例如“$ 5”。相反,写作\ 5 或 者 [ 5或者[ 5[]5,我们可以输入

Pattern.quote("$5");
5.为什么String.split()需要转义管道分隔符?

字符串。split()在给定正则表达式的匹配项周围分割一个字符串。Java表达式支持影响模式匹配方式的特殊字符,称为元字符。|是一个元字符,用于匹配几个可能的正则表达式中的单个正则表达式。例如,A|B表示A或者B。有关详细信息,请参阅垂直条或管道符号的交替。因此,要|用作文字,你需要通过\在它前面添加来逃避它,就像\|。

6.我们怎样才能匹配ñ b ň与Java正则表达式?

这是由一定数量的所有非空字符串的语言a的后面是数量相等b的,如ab,aabb和aaabbb。这种语言可以显示为无上下文语法S→aSb | ab,因此是一种非常规语言。

但是,Java正则表达式实现可以识别的不仅仅是常规语言。也就是说,它们不是形式语言理论定义的“规则”。使用先行和自引用匹配将实现它。在这里,我将首先给出最终的正则表达式,然后稍微解释一下。有关综合解释,我建议您阅读如何使用Java正则表达式匹配^ nb ^ n。

Pattern p = Pattern.compile("(?x)(?:a(?= a*(\1?+b)))+\1");
// true
System.out.println(p.matcher(“aaabbb”).matches());
// false
System.out.println(p.matcher(“aaaabbb”).matches());
// false
System.out.println(p.matcher(“aaabbbb”).matches());
// false
System.out.println(p.matcher(“caaabbb”).matches());
我不想解释这个复杂的正则表达式的语法,而是想说一下它是如何工作的。

在第一次迭代中,它在第一次迭代时停止,a然后向前看(在跳过一些as后使用a*)是否存在b。这是通过使用来实现的(?:a(?= a*(\1?+b)))。如果匹配,\1则自引用匹配将匹配内部括号元素,这是b第一次迭代中的单个元素。
在第二次迭代中,表达式将在第二次迭代时停止a,然后它向前看(再次跳过as)以查看是否存在b。但这次,\1+b实际上相当于bb,因此两个b必须匹配。如果是这样,\1将bb在第二次迭代后更改为。
在第n次迭代中,表达式在第n个停止,a并查看前面是否有n b。
通过这种方式,表达式可以计算as 的数量并且如果b后面的s 的数量a相同则匹配。

7.如何用字符串中的单个空格替换2个或更多个空格并仅删除前导空格?

字符串。replaceAll()用给定的替换替换与给定正则表达式匹配的每个子字符串。“2个或更多个空格”可以用正则表达式表示[ ]+。因此,以下代码将起作用。请注意,解决方案最终不会删除所有前导和尾随空格。如果您想删除它们,可以使用String。管道中的trim()。

String line = " aa bbbbb ccc d “;
// " aa bbbbb ccc d "
System.out.println(line.replaceAll(”[\s]+", " "));
8.如何确定一个数字是否是正则表达式的素数?

public static void main(String[] args) {
// false
System.out.println(prime(1));
// true
System.out.println(prime(2));
// true
System.out.println(prime(3));
// true
System.out.println(prime(5));
// false
System.out.println(prime(8));
// true
System.out.println(prime(13));
// false
System.out.println(prime(14));
// false
System.out.println(prime(15));
}
public static boolean prime(int n) {
return !new String(new char[n]).matches(".?|(…+?)\1+");
}
该函数首先生成n个字符,并尝试查看该字符串是否匹配.?|(…+?)\1+。如果是素数,则表达式将返回false并且!将反转结果。

第一部分.?只是试图确保1不是引物。神奇的部分是使用反向引用的第二部分。(…+?)\1+首先尝试匹配n个字符长度,然后重复几次\1+。

根据定义,素数是大于1的自然数,除了1和自身之外没有正除数。这意味着如果a = n * m则a不是素数。n * m个可进一步解释“重复Ñ 米倍”,而这正是正则表达式的作用:匹配Ñ通过使用字符的长度(…+?),然后重复它米通过使用倍\1+。因此,如果模式匹配,则数字不是素数,否则为。提醒那!将扭转结果。

9.如何拆分以逗号分隔的字符串但忽略引号中的逗号?

你已经达到正则表达式崩溃的程度。编写一个简单的拆分器更好更整洁,并根据需要处理特殊情况。

或者,您可以通过使用switch语句或if-else来模仿有限状态机的操作。附件是一段代码。

public static void main(String[] args) {
String line = “aaa,bbb,“c,c”,dd;dd,“e,e”;
List toks = splitComma(line);
for (String t : toks) {
System.out.println(”> " + t);
}
}
private static List splitComma(String str) {
int start = 0;
List toks = new ArrayList();
boolean withinQuote = false;
for (int end = 0; end < str.length(); end++) {
char c = str.charAt(end);
switch© {
case ‘,’:
if (!withinQuote) {
toks.add(str.substring(start, end));
start = end + 1;
}
break;
case ‘"’:
withinQuote = !withinQuote;
break;
}
}
if (start < str.length()) {
toks.add(str.substring(start));
}
return toks;
}
10.如何在Java正则表达式中使用反向引用

反向引用是Java正则表达式中的另一个有用功能。

好久到没有去写关于正则表达式的总结了,虽然自己写了一些关于正则表达式的东西。但是

​ 感觉上对正则表达式还停留在网上查找的阶段,对于大部分的人来说,很难写自己的正则表达式

​ 对于正则表达式笔者也做过相关的总结。呃,过了一段时间还是模糊了。因此找一些练习题来找

​ 回自己的记忆。

​ 需要说明的是这些练习题有的是网上的!

初级练习

​ 1、求非负整数 : ^\d+$

​ Tips:需要注意的是这个匹配模式为多行模式下进行的

img

​ 2、匹配正整数: 16[1-9][0-9]$ 在网上也有这种写法的 17[1-9][0-9]$

​ 这里截图我也不贴了,前者指能匹配123012这种整数,而后者可以匹配001230。

​ 取舍就看实际的需要了

​ 3、非正整数:^(-\d+|(0+))$

​ 4、负整数:^-[0-9][1-9][0-9]$

​ 5、整数 :^-?\d+$

​ 6、非负浮点数 :^\d+(.\d+)?$

​ 7、正浮点数 :^(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9]))$

​ 8、非正浮点数 :^((-\d+(.\d+)?)|(0+(.0+)?))$

​ 9、负浮点数:^(-(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9])))$

​ 10、浮点数:^(-?\d+)(.\d+)?$

​ 11、有数字、26个英文字母组成的字符串:18+$

中级练习

​ 1、长度为8-10的用户密码(以字母开头、数字、下划线)

19\w{7,10}$

​ 2、验证输入只能是汉字 : 20{0,}$

​ 3、电子邮箱验证:^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$

​ 4、URL地址验证:^http://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$

​ 5、电话号码的验证:请参考:http://blog.csdn.net/kiritor/article/details/8733469

​ 6、简单的身份证号验证:\d{15}|\d{18}$

​ …

高级练习

​ 1、提取并捕获html标签内容:

>]*)+href=([ >])(?: [^>])*>

img

img

Java正则表达式练习

目录

  一、导读
  二、正则表达式の规则
  三、字符串の匹配:matches()
  四、字符串の切割:split()
  五、字符串の替换:replaceAll()
  六、字符串の获取:
  七、进阶:综合练习
  八、总结

一、导读

正则表达式,又称规则表达式。(英文名Regular Expression,所以代码中常以regex、regexp、RE表示)。正则表达式简单说就是用于操作文本数据的规则表达式,在Java中我们使用正则表达式来对字符串进行“有规则的操作”,没理解没关系,看下面的练习就懂了。

正则表达式对字符串的常见操作有:字符串的匹配、切割、替换、获取。下面我们就逐一进行练习:

二、正则表达式の规则

既然是表达式,就具有特定的规则,所以我们先看看jdk的工具类Pattern对正则表达式的规则的描述:(较多,简单浏览即可,当使用到对应的规则是来查阅即可。)

正则练习题_第1张图片

三、字符串の匹配:matches()

练习1:对输入的qq号进行匹配(qq匹配规则:长度为5-10位,纯数字组成,且不能以0开头。)

没有学习正则表示式之前,我们需要用各种if语句来进行判断,但现在我们可以使用则正表达式的规则来操作:

[复制代码](javascript:void(0)

 1 package RegularExpression;
 2 
 3 public class regexTest {
 4     public static void main(String[] args) {
 5         //测试:
 6         String qq1 = "1832137835";
 7         String qq2 = "789j9371";
 8         String qq3 = "22";
 9         String qq4 = "012189783";
10         boolean b1 = isQQ(qq1);
11         boolean b2 = isQQ(qq2);
12         boolean b3 = isQQ(qq3);
13         boolean b4 = isQQ(qq4);
14         
15         System.out.println(qq1+"是qq号码吗?"+b1);
16         System.out.println(qq2+"是qq号码吗?"+b2);
17         System.out.println(qq3+"是qq号码吗?"+b3);
18         System.out.println(qq4+"是qq号码吗?"+b4);
19     }
20     
21     //练习1:匹配QQ号(长度为5-10位,纯数字组成,且不能以0开头)
22     public static boolean isQQ(String qq) {
23         //定义匹配规则:
24         String regex = "[1-9][0-9]{4,9}";
25         
26         //判断是否符合规则
27         boolean b = qq.matches(regex);
28         
29         return b;
30     }
31 }

[复制代码](javascript:void(0)

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LChwOkKP-1590934377404)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027170223164-394904581.png)]

解析:注意匹配规则被“浓缩”到了字符串regex中,我们只需要用"[1-9][0-9]{4,9}"就描述了qq的匹配规则,怎么做到的呢?

首先我们在匹配需要“一位一位地匹配”,qq匹配规则是第一位不能是0的纯数字,所以我们用[1-9]来表示第一位的规则;接下来是第二位:随意的数字都行,所以我们用[0-9]来表示,按照这个逻辑,当然后面的都应该是纯数字即[0-9],但我们需要确定qq的长度只能是510,而规则里我们用{}来表示范围,即[0-9]{4,9}结合起来就表示:49个纯数字。

总的来说就是:[1-9]规定第一位只能是19即不为0的纯数字,而[0-9]{4,9}则规定可输入49个纯数字,加起来刚好是:首位不为0的长度为5~10的纯数字。

上面使用的规则如[]、{}等特殊符号在标题二中都能找到,对于这些常用的符号我们记住就好。

练习2:对输入的电话号码进行匹配(匹配要求:匹配成功的电话号码位数为11位的纯数字,且以1开头,第二位必须是:3、7、8中的一位,即只匹配13*********、17*********、18*********的电话号码)。

解析:同练习1一样,首先我们使用字符串regex对匹配规则进行描述,一位一位地匹配,所以,开头必须是数字1,那么我们可以写[1]来表示(不过对于只有一个字符的描述,可省略[]);接下来描述第二个字符:只能是3、7、8,所以我们使用[378]来表示。然后后9位号码只要是数字就可以了,所以我们可以用[0-9]{9}来表示。连起来就是:regex = “1[378][0-9]{9}”。

我们用代码来实现一下:

[复制代码](javascript:void(0)

 1 package RegularExpression;
 2 
 3 public class regexTest {
 4     public static void main(String[] args) {
 5         //测试:
 6         String t1 = "13745678901";
 7         String t2 = "12745678901";
 8         String t3 = "121213121212";
 9         String t4 = "23333333333";
10         boolean b1 = isQQ(t1);
11         boolean b2 = isQQ(t2);
12         boolean b3 = isQQ(t3);
13         boolean b4 = isQQ(t4);
14         
15         System.out.println(t1+"是电话号码吗?"+b1);
16         System.out.println(t2+"是电话号码吗?"+b2);
17         System.out.println(t3+"是电话号码吗?"+b3);
18         System.out.println(t4+"是电话号码吗?"+b4);
19     }
20     
21     //练习2:匹配电话号吗(以1开头第二位必须是3/7/8的11位纯数字组成)
22     public static boolean isQQ(String qq) {
23         //定义匹配规则:
24         String regex = "1[378][0-9]{9}";
25         
26         //判断是否符合规则
27         boolean b = qq.matches(regex);
28         
29         return b;
30     }
31 }

[复制代码](javascript:void(0)

打印结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AW413Fzx-1590934377408)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027170905226-1222253256.png)]

[一个小细节]:除了用[0-9]表示纯数字还可以用\d来表示(上面规则里有可以往上look),所以我们还可以令regex = “1[378]\d{9}”。(在java中\需要用\来转义,所以写为\d而不是\d)。

四、字符串の切割:split()

对字符串进行切割就是对一个字符串按照某个或某些字符进行切割,从而变成若干字符串。如“张三、李四、王五”,我们如果按照“、”来切割就变成三个字符串:“张三”,“李四”,“王五”。(切割的实质其实就是先进行字符串匹配,将匹配到的字符串“丢弃”,并将丢掉的前面部分和剩下的部分变成字符串)。

练习1:对字符串“张三@@@李四@@王五@茅台”进行切割,去掉@符号。

分析:首先我们要去掉字符串中的若干个@符号,如果只有一个@符号我们可以用直接用@来匹配,但这里的@是不确定的,所以我们要用到规则中的:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eifD543W-1590934377410)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027172939070-293166036.png)]

所以我们用@+来表示:@这个符号至少出现一次这种情况,现在我们可以来看看具体的代码:

[复制代码](javascript:void(0)

 1 package RegularExpression;
 2 
 3 public class splitTest {
 4     public static void main(String[] args) {
 5         //练习1:切割字符串"张三@@@李四@@王五@茅台".
 6         String s = "张三@@@李四@@王五@茅台";
 7         
 8         //描述切割规则:以若干@来切割
 9         String regex = "@+";
10         
11         //切割后的字符串数组:
12         String[] ss = s.split(regex);
13         
14         for(String string:ss){
15             System.out.println(string);
16         }
17         
18     }
19 }

[复制代码](javascript:void(0)

打印结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z8Ak2Ovt-1590934377413)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027174014492-189464459.png)]

练习2:【以叠词切割】:如字符串"abccsasahhhz"按“叠词”来切割就变成了“ab”,“sasa”,“z”。因为“cc”、“hhh”都是叠词,需要切割掉。现在请将字符串“张三@@@李四¥¥王五ssssssss江流儿”按照叠词切割。

分析:关键点在于如何表示叠词呢?连续出现两个以上的相同字符即为叠词,首先我们要表示任意字符:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A345jhOl-1590934377414)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027174634758-1981957062.png)]

我们使用“.”来表示任意字符,接着我们需要表示两个这样的字符:这里我们需要使用到“组”的概念:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x5FZGO9O-1590934377415)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027181448508-420466147.png)]

即使用括号:()来表示组,那么组是干嘛的?我们就可以 对组中的数据进行引用:那么regex = "(.)\1"就表示:某一字符出现了两次(注意首先我们用(.)来表示任意字符,而\1是对组(.)中的字符进行复用,合起来就是:两个相同的字符),现在我们不只是需要出现两次的字符,所以使用+号来表示出现多次,最终叠词就表示为:regex = “(.)\1+”。

看具体实现代码:

[复制代码](javascript:void(0)

 1 package RegularExpression;
 2 
 3 public class splitTest {
 4     public static void main(String[] args) {
 5         //练习2:"张三@@@李四¥¥王五ssssssss江流儿"按叠词切割.
 6         String s = "张三@@@李四¥¥王五ssssssss江流儿";
 7         
 8         //叠词切割
 9         String regex = "(.)\\1+";
10         
11         //切割后的字符串数组:
12         String[] ss = s.split(regex);
13         
14         for(String string:ss){
15             System.out.println(string);
16         }
17         
18     }
19 }

[复制代码](javascript:void(0)

切割结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GaDTuhaJ-1590934377417)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027182359461-1491970444.png)]

[一个小细节]:转义字符的使用

对于“haha.lisi.nihao”这样的字符串如果要用".“来切割,要怎么办呢?可能你会说定义regex=”."不就哦了吗?但是如果你代码真这样写的话,你的输出结果就会像你的脑海一样“一片空白”。注意:“.”这个符号在正则表达式中是有特殊意义的:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aXwC9DTw-1590934377418)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027174634758-1981957062.png)]

这个小点可以代表任何字符,所以我们需要用转义字符\来将“.”转义为普通的点,所以只要把regex = "\."即可。

五、字符串の替换:replaceAll()

利用正则表达式进行字符串替换其实是先匹配指定字符串中的字符,然后再用自定义字符替换掉匹配到的字符串。

练习一:将字符串“张三@@@李四YYY王五*****王尼玛”中的叠词替换为:“、”。

分析:第一步是匹配叠词:上面的练习中我们已经知道regex = "(.)\1+"可以表示叠词,所以第二部就可以使用replaceAll()方法进行替换了:

[复制代码](javascript:void(0)

 1 package RegularExpression;
 2 
 3 public class replaceAllTest {
 4     public static void main(String[] args) {
 5         //练习1:将字符串“张三@@@李四YYY王五*****王尼玛”中的叠词替换为:“、”。
 6         String str = "张三@@@李四YYY王五*****王尼玛";
 7         
 8         //匹配规则
 9         String regex = "(.)\\1+";
10         
11         //替换为:
12         String newStr = str.replaceAll(regex, "、");
13         
14         //替换后结果:
15         System.out.println(newStr);
16     }
17     
18 }

[复制代码](javascript:void(0)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GJyjJaCc-1590934377421)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027184953773-46556458.png)]

练习二:将“张三@@@李四YYY王五*****王尼玛”中的叠词替换为单字符,即结果为:“张三@李四Y王五*王尼玛”。

分析:这个练习和练习1很像,首先我们都需要匹配到叠词,但是替换的内容却不是固定的“、”了,我们需要将叠词替换为它本身的字符,所以我们需要引用组的内容,我们可以使用$1来复用组中第1组的值(即叠词的字符):

[复制代码](javascript:void(0)

 1 package RegularExpression;
 2 
 3 public class replaceAllTest {
 4     public static void main(String[] args) {
 5         //练习2:将“张三@@@李四YYY王五*****王尼玛”中的叠词替换为单字符,即结果为:“张三@李四Y王五*王尼玛”。
 6         String str = "张三@@@李四YYY王五*****王尼玛";
 7         
 8         //匹配规则
 9         String regex = "(.)\\1+";
10         
11         //替换为:
12         String newStr = str.replaceAll(regex, "$1");
13         
14         //替换后结果:
15         System.out.println(newStr);
16     }
17     
18 }

[复制代码](javascript:void(0)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zIIzIZ8M-1590934377423)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027185642351-1466368028.png)]

六、字符串の获取:

正则表达式其实是封装成了Pattern类,所以字符串的匹配、切割、替换都是调用了Pattern类中的方法。所以如果我们需要获取指定字符串中的子串,首先同样的我们需要进行字符串匹配,然后判断指定字符串中是否有匹配的子串,有就获取,没有就获取不到。

获取子串的步骤:

1、描述要获取的子串:匹配子串

2、使用正则表达式的封装类Pattern来获取匹配器

3、使用匹配器中的方法group()获取字符串的匹配的子串

练习:获取字符串“Hi ! Don’t be moved by yourself Fzz”中为两个字母的单词。即Hi、be、by。

分析:根据上面的步骤:

第一步,我们要对子串进行匹配,即两个字母的单词,字母可以用[a-zA-Z]来表示,范围是两个,所以regex = “[a-zA-Z]{2}”。

但这样不够准确,我们需要的是单词,而不是三个字母,所以要用到“边界匹配器”,即

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a20QBHZa-1590934377424)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027202139586-1479982109.png)]

单词边界:\b,所以regex = “\b[a-zA-Z]{2}\b”。

然后是第二步:获取匹配器

1 Pattern p = Pattern.compile(regex);
2 Matcher m = p.matcher(s);

最后一步:使用匹配器来获取匹配到的字符串

1 while(m.find()){
2     System.out.println(m.group());
3  }

我们来看看总体的实现代码:

[复制代码](javascript:void(0)

 1 package RegularExpression;
 2 
 3 import java.util.regex.Matcher;
 4 import java.util.regex.Pattern;
 5 
 6 public class groupTest {
 7     public static void main(String[] args) {
 8         String s = "Hi ! Don't be moved by yourself Fzz";
 9         
10         //1、匹配子串
11         String regex = "\\b[a-zA-Z]{2}\\b";
12         
13         //2、获取匹配器
14         Pattern p = Pattern.compile(regex);
15         Matcher m = p.matcher(s);
16         
17         //3、使用匹配器的group()方法来获取:(find方法是判断是否具有匹配子串)、
18         System.out.println("”"+s+"“中的两个字母的单词有:");
19         while(m.find()){
20             System.out.println(m.group());
21         }
22     }
23 }

[复制代码](javascript:void(0)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j4fqGZRv-1590934377426)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027204141695-786553500.png)]

七、进阶:综合练习

练习一:口吃怎么办?需求:请将下面的字符串“我我我……我我……爱…爱爱……学…学……学编程”改为:“我爱学编程”。

分析:首先我们可以将字符串中的“……”去掉,然后就可以将叠词替换为单个汉字即可。

[复制代码](javascript:void(0)

 1 package RegularExpression;
 2 
 3 public class test {
 4     public static void main(String[] args) {
 5         //口吃怎么办?将“我我我……我我……爱…爱爱……学…学……学编程”改为“我爱学编程”。
 6         String str = "我我我......我我......爱...爱爱...学...学......学编程";
 7         //1、首先去掉...(将.替换为""即可)
 8         String regex = "\\.";
 9         String str1 = str.replaceAll(regex,"");
10         System.out.println("1:"+str1);
11         //2、替代叠词
12         regex = "(.)\\1+";
13         String str2 = str1.replaceAll(regex, "$1");
14         System.out.println("2:"+str2);
15     }
16 }

[复制代码](javascript:void(0)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QFQ1rKlg-1590934377429)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027212400383-1061665456.png)]

练习二:网络爬虫spider(专门获取指定规则数据的程序)。需求:在某一个网页中获取该网页中出现的特定信息,比如获取该网页中出现的邮箱地址。(其实这就是网页爬虫的简单运用:获取邮箱。)

**分析:**首先我们随便百度一个网页吧:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KIYvIlZn-1590934377429)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027220543758-1510277721.png)]

首先我们就以第一个网页为例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L4bTqDUz-1590934377430)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027220822726-1492470730.png)]

我们可以看到里面有超多的qq邮箱,现在我们就来获取这个网页里的qq邮箱。

1、首先我们要获取这个网页的html文档,方便获取其中的文字信息。现在我将这个文件保存在了本地方便操作。可以看一下用记事本打开的效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rfv1wyct-1590934377431)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027224746726-1777776702.png)]

2、然后我们就需要使用IO流来读取这个html文档

3、对读取的文档利用正则表达式规则进行特定字符串(即qq邮箱)的获取

img spiderTest

这就是我们获取到的邮箱:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I7JpG7mB-1590934377432)(https://images2017.cnblogs.com/blog/1250367/201710/1250367-20171027225140273-1446745483.png)]

八、总结

正则表达式还有很多规则需要我们去深入学习,对于正则表达式,它的优点就是简化了字符串的操作,缺点是我们需要学习这些特点的规则,而且符号过多时不方便阅读。

一、正则表达式简介
正则表达式是使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。爬虫中解析html可以使用正则来方便的提取信息

二、正则表达式匹配规则
模式 描述
\w 匹配字母、数字、下划线
\W 匹配非字母、数字、下划线
\s 匹配任意空白字符,相当于[\t\n\r\f]
\S 匹配任意非空字符
\d 匹配任意数字,相当于[0-9]
\D 匹配非数字的字符
\A 匹配字符串开头
\Z 匹配字符串结尾,如果存在换行,只匹配到换行前的结束字符串
\z 匹配字符串结尾,如果存在换行,同时还会匹配换行符
\G 匹配最后匹配完成的位置
\n 匹配一个换行符
\t 匹配一个制表符
^ 匹配一行字符串的开头
$ 匹配一行字符串的结尾
. 匹配任意字符,除了换行符
[^…] 不在[]中的字符,比如[^abc]匹配除了a、b、c之外的字符

  • 匹配0个或多个表达式

  • 匹配1个或多个表达式
    ? 匹配0个或1个前面的正则表达式定义的片段,非贪婪方式
    () 匹配括号内的表达式,也表示一个组
    {n} 精确匹配n个前面的表达式,比如\d{n},代表n个数字
    {n,m} 匹配n到m次由前面正则表达式定义的片段,贪婪方式
    代码实战:

public class RegexAction {
public static void main(String[] args) {
String s = “Hello 123 4567 World_This is a Regex Demo”;
//match_1(s);
//match_2(s);
//match_3(s);
//match_4(s);
//match_5(s);
match_6(s);
}

private static void match_1(String s) {
    Pattern pattern = Pattern.compile("^Hello\\s\\d\\d\\d\\s\\d{4}\\s\\w{10}");
    Matcher matcher = pattern.matcher(s);

    if(matcher.find()) {
        System.out.println(matcher.group(0));
    }
}

private static void match_2(String s) {
    Pattern pattern = Pattern.compile("Hello\\s(\\d+)\\s\\d{4}\\s\\w{10}");
    Matcher matcher = pattern.matcher(s);

    if(matcher.find()) {
        System.out.println(matcher.group(0));  //匹配到的整个结果
        System.out.println(matcher.group(1));  //匹配到的第一个括号中的结果
    }
}

private static void match_3(String s) {
    Pattern pattern = Pattern.compile("Hello\\s(\\d*)\\s\\d{4}\\s\\w{10}");
    Matcher matcher = pattern.matcher(s);

    if(matcher.find()) {
        System.out.println(matcher.group(0));  //匹配到的整个结果
        System.out.println(matcher.group(1));  //匹配到的第一个括号中的结果
    }
}

private static void match_4(String s) {
    Pattern pattern = Pattern.compile("Hello.*Demo");
    Matcher matcher = pattern.matcher(s);

    if(matcher.find()) {
        System.out.println(matcher.group(0));  //匹配到的整个结果
    }
}

/**
 * 贪婪匹配
 * 匹配中间数字,只能得到7
 * .*会尽可能多的匹配数据
 * @param s
 */
private static void match_5(String s) {
    Pattern pattern = Pattern.compile("Hello.*(\\d+).*Demo");
    Matcher matcher = pattern.matcher(s);

    if(matcher.find()) {
        System.out.println(matcher.group(1));  //匹配到的整个结果

    }

}

/**
 * .*?非贪婪匹配
 * @param s
 */
private static void match_6(String s) {
    Pattern pattern = Pattern.compile("Hello.*?(\\d+).*Demo");
    Matcher matcher = pattern.matcher(s);
    if(matcher.find())  {
        System.out.println(matcher.group());
        System.out.println(matcher.group(1));
    }
}

/**
 * 正则表达式字符串也可以不编译直接使用
 * @param s
 */
private static void match_7(String s) {
    String regex = "Hello.*?(\\d+).*Demo";
    boolean flag = s.matches(regex);
    System.out.println(flag);
}
}

Pattern 类
pattern 对象是一个正则表达式的编译表示

Matcher 类
Matcher 对象是对输入字符串进行解释和匹配操作的引擎

find()方法
尝试查找与该模式匹配的输入序列的下一个子序列,直到搜索到输入序列结束
可以从指定位置开始匹配find(int start)

一、校验数字的表达式

1 数字:21$
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 有两位小数的正实数:22+(.[0-9]{2})?$
10 有1~3位小数的正实数:23+(.[0-9]{1,3})?$
11 非零的正整数:24\d
$ 或 ^([1-9][0-9]){1,3}$ 或 ^+?[1-9][0-9]$
12 非零的负整数:^-[1-9][]0-9"$ 或 ^-[1-9]\d$
13 非负整数:^\d+$ 或 25\d*|0$
14 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
15 非负浮点数:^\d+(.\d+)?$ 或 26\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 正浮点数:27\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 汉字:28{0,}$
2 英文和数字:29+$ 或 30{4,40}$
3 长度为3-20的所有字符:^.{3,20}$
4 由26个英文字母组成的字符串:31+$
5 由26个大写英文字母组成的字符串:32+$
6 由26个小写英文字母组成的字符串:33+$
7 由数字和26个英文字母组成的字符串:34+$
8 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
9 中文、英文、数字包括下划线:35+$
10 中文、英文、数字但不包括下划线等符号:36+$ 或 37{2,20}$
11 可以输入含有^%&’,;=?KaTeX parse error: Can't use function '\"' in math mode at position 1: \̲"̲等字符:[^%&',;=?\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位身份证:38\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$
18位身份证:39\d{5}[1-9]\d{3}((0\d)|(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字节,允许字母数字下划线):40[a-zA-Z0-9_]{4,15}$
10 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):41\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”:42[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开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:43+(.[0-9]+)?$
20 5.必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 “10” 和 “10.2” 是通过的:44+(.[0-9]{2})?$
21 6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:45+(.[0-9]{1,2})?$
22 7.这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:46{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 空白行的正则表达式:\n\s*\r (可以用来删除空白行)
29 HTML标记的正则表达式:<(\S*?)[^>]>.?|<.? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
30 首尾空白字符的正则表达式:^\s
|\s*KaTeX parse error: Undefined control sequence: \s at position 4: 或(^\̲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地址时有用)


  1. \u4e00-\u9fa5_a-zA-Z0-9 ↩︎

  2. a-zA-Z0-9_\u4e00-\u9fa5 ↩︎

  3. \u4E00-\u9FA5 ↩︎

  4. \u4e00-\u9fa5 ↩︎

  5. a-zA-Z0-9 ↩︎

  6. a-zA-Z ↩︎

  7. 1-9 ↩︎

  8. 1-9 ↩︎

  9. A-Za-z ↩︎

  10. a-z ↩︎

  11. 0-9 ↩︎

  12. 0-9 ↩︎

  13. A-Za-z ↩︎

  14. a-z ↩︎

  15. u4e00-u9fa5 ↩︎

  16. 1-9 ↩︎

  17. 0-9 ↩︎

  18. A-Za-z0-9 ↩︎

  19. a-zA-Z ↩︎

  20. \u4e00-\u9fa5 ↩︎

  21. 0-9 ↩︎

  22. 0-9 ↩︎

  23. 0-9 ↩︎

  24. 1-9 ↩︎

  25. 1-9 ↩︎

  26. 1-9 ↩︎

  27. 1-9 ↩︎

  28. \u4e00-\u9fa5 ↩︎

  29. A-Za-z0-9 ↩︎

  30. A-Za-z0-9 ↩︎

  31. A-Za-z ↩︎

  32. A-Z ↩︎

  33. a-z ↩︎

  34. A-Za-z0-9 ↩︎

  35. \u4E00-\u9FA5A-Za-z0-9_ ↩︎

  36. \u4E00-\u9FA5A-Za-z0-9 ↩︎

  37. \u4E00-\u9FA5A-Za-z0-9 ↩︎

  38. 1-9 ↩︎

  39. 1-9 ↩︎

  40. a-zA-Z ↩︎

  41. a-zA-Z ↩︎

  42. 1-9 ↩︎

  43. 0-9 ↩︎

  44. 0-9 ↩︎

  45. 0-9 ↩︎

  46. 0-9 ↩︎

你可能感兴趣的:(java基础)