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

java正则表达式纪录

2015-10-09 15:40 218 查看
程序员的七种基本基础技能:数组,字符串与哈希表、正则表达式、调试、两门语言、一个开发环境、SQL 语言和编写软件的思想。

正则表达式(regular expressions)是一种描述字符串集的方法,它是以字符串集中各字符串的共有特征为依据的。正则表达式可以用于搜索、编辑或者是操作文本和数据。它超出了
Java 程序设计语言的标准语法,因此有必要去学习特定的语法来构建正则表达式。

我们通过 java.util.regex API来学习正则表达式。

java.util.regex 包主要由三个类所组成:Pattern、Matcher 和 PatternSyntaxException。

Pattern 对象表示一个已编译的正则表达式。Pattern 类没有提供公共的构造方法。要构建一个模式,首先必须调用公共的静态 compile 方法,它将返回一个 Pattern 对象。这个方法接受正则表达式作为第一个参数。
Matcher 是一个靠着输入的字符串来解析这个模式和完成匹配操作的对象。与 Pattern 相似,Matcher 也没有定义公共的构造方法,需要通过调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
PatternSyntaxException 对象是一个未检查异常,指示了正则表达式中的一个语法错误。
1元字符

  API 也支持许多可以影响模式匹配的特殊字符。把正则表达式改为wqb.并输入字符串“wqbs”,输出如下所示:

1
Enter
your regex: wqb.
2
Enter
input string to search: wqbs
3
I
found the text 
"wqbs"
 
starting
at index 
0
 
and
ending at index 
4
.
  虽然在输入的字符串中没有点(.),但这个匹配仍然是成功的。这是由于点(.)是一个元字符(metacharacters)(被这个匹配翻译成了具有特殊意义的字符了)。这个例子为什么能匹配成功的原因在于,元字符.指的是“任意字符”。

注意:在学习过更多的如何构建正则表达式后,你会碰到这些情况:上面的这些特殊字符不应该被处理为元字符。然而也能够使用这个清单来检查一个特殊的字符是否会被认为是元字符。例如,字符 !、@ 和 # 决不会有特殊的意义。

  有两种方法可以强制将元字符处理成为普通字符:

  1. 在元字符前加上反斜线(\);

  2. 把它放在\Q(引用开始)和\E(引用结束)之间。在使用这种技术时,\Q和\E能被放于表达式中的任何位置(假设先出现\Q)

2

字符类
[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]]除 b 和 c 之外的 a 到 z 字符:[ad-z](差集)
[a-z&&[^m-p]]a 到 z,并且不包括 m 到 p:[a-lq-z](差集)
  左边列指定正则表达式构造,右边列描述每个构造的匹配的条件。

注意:“字符类(character class)”这个词中的“类(class)”指的并不是一个 .class 文件。在正则表达式的语义中,字符类是放在方括号里的字符集,指定了一些字符中的一个能被给定的字符串所匹配。

   3简单类(Simple Classes

  字符类最基本的格式是把一些字符放在一对方括号内。例如:正则表达式[bcr]at会匹配“bat”、“cat”或者“rat”,这是由于其定义了一个字符类(接受“b”、“c”或“r”中的一个字符)作为它的首字符。

01
Enter
your regex: [wqb]at
02
Enter
input string to search: wat
03
I
found the text 
"wat"
 
starting
at index 
0
 
and
ending at index 
3
.
04
 
05
Enter
your regex: [wqb]at
06
Enter
input string to search: qat
07
I
found the text 
"qat"
 
starting
at index 
0
 
and
ending at index 
3
.
08
 
09
Enter
your regex: [wqb]at
10
Enter
input string to search: bat
11
I
found the text 
"bat"
 
starting
at index 
0
 
and
ending at index 
3
.
12
 
13
Enter
your regex: [wqb]at
14
Enter
input string to search: hat
15
No
match found.
  在上面的例子中,在第一个字符匹配字符类中所定义字符中的一个时,整个匹配就是成功的。

4 否定

  要匹配除那些列表之外所有的字符时,可以在字符类的开始处加上^元字符,这种就被称为否定(negation)。

01
Enter
your regex: [^wqb]at
02
Enter
input string to search: wat
03
No
match found.
04
 
05
Enter
your regex: [^wqb]at
06
Enter
input string to search: qat
07
No
match found.
08
 
09
Enter
your regex: [^wqb]at
10
Enter
input string to search: bat
11
No
match found.
12
 
13
Enter
your regex: [^wqb]at
14
Enter
input string to search: hat
15
I
found the text 
"hat"
 
starting
at index 
0
 
and
ending at index 
3
.
  在输入的字符串中的第一个字符不包含在字符类中所定义字符中的一个时,匹配是成功的。

5预定义字符类

  Pattern 的 API 包有许多有用的预定义字符类(predefined character classes),提供了常用正则表达式的简写形式。
预定义字符类
.任何字符(匹配或者不匹配行结束符)
\d数字字符:[0-9]
\D非数字字符:[^0-9]
\s空白字符:[\t\n\x0B\f\r]
\S非空白字符:[^\s]
\w单词字符:[a-zA-Z_0-9]
\W非单词字符:[^\w]
  上表中,左列是构造右列字符类的简写形式。例如:\d指的是数字范围(0~9),\w指的是单词字符(任何大小写字母、下划线或者是数字)。无论何时都有可能使用预定义字符类,它可以使代码更易阅读,更易从难看的字符类中排除错误。

  以反斜线(\)开始的构造称为转义构造(escaped constructs)。回顾一下在 字符串 一节中的转义构造,在那里我们提及了使用反斜线,以及用于引用的\Q和\E。在字符串中使用转义构造,必须在一个反斜线前再增加一个反斜用于字符串的编译,例如:

private final String REGEX = "\\d";        // 单个数字

  这个例子中\d是正则表达式,另外的那个反斜线是用于代码编译所必需的。

 6 量词

  我们来看一下贪婪(greedy)、勉强(reluctant)和侵占(possessive)量词,来匹配指定表达式X的次数。

  量词(quantifiers)允许指定匹配出现的次数,方便起见,当前 Pattern API 规范下,描述了贪婪、勉强和侵占三种量词。首先粗略地看一下,量词X?、X??和X?+都允许匹配 X 零次或一次,精确地做同样的事情,但它们之间有着细微的不同之处,在这节结束前会进行说明。
量 词 种 类意  义
贪婪勉强侵占
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 次
7

边界匹配器
^行首
$行尾
\b单词边界
\B非单词边界
\A输入的开头
\G上一个匹配的结尾
\Z输入的结尾,仅用于最后的结束符(如果有的话)
\z输入的结尾
eg:

String regEx = "^[0][0-9]$";
Pattern pattern = Pattern.compile(regEx);
Matcher matcher = pattern.matcher(s.toString());
boolean rs = matcher.find();
if(rs){
s.clear();
}

Java 常用正则表达式

1. 身份证号码:
1) 身份证正则表达式(15位) ^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$
forJava:
 Pattern p = Pattern.compile("^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$");
------ ------ ------ 说明 start ------ ------ ------
15位身份证号码各位的含义: 
1-2位省、自治区、直辖市代码; 
3-4位地级市、盟、自治州代码; 
5-6位县、县级市、区代码; 
7-12位出生年月日,比如670401代表1967年4月1日,与18位的第一个区别; 
13-15位为顺序号,其中15位男为单数,女为双数;
------ ------ ------ 说明 end ------ ------ ------
2) 身份证正则表达式(18位)^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$
forJava:
 Pattern p = Pattern.compile("^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{4}$");
------ ------ ------ 说明 start ------ ------ ------
18位身份证号码各位的含义: 
1-2位省、自治区、直辖市代码; 
3-4位地级市、盟、自治州代码; 
5-6位县、县级市、区代码; 
7-14位出生年月日,比如19670401代表1967年4月1日; 
15-17位为顺序号,其中17位(倒数第二位)男为单数,女为双数; 
18位为校验码,0-9和X。作为尾号的校验码,是由把前十七位数字带入统一的公式计算出来的,计算的结果是0-10,
如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位。X是罗马数字的10,用X来代替10。
------ ------ ------ 说明 end ------ ------ ------

2. 电话号码:
1) 移动电话:
 ^((13[0-9])|(15[^4,\D])|(18[0-9]))\d{8}$
------ ------ ------ 说明 start ------ ------ ------
中国电信手机号码开头数字 133、1349、153、180、181、189
中国联通手机号码开头数字 130、131、132、145、155、156、185、186
中国移动手机号码开头数字 1340-1348、135、136、137、138、139、147、150、151、152、157、158、159、182、183、184、187、188 
补充:14开头的号码以前为上网卡专属号段,如联通的是145,移动的是147等等。不过现在14开头的号码也可以使用语音通话等全部业务,不受限制。
------ ------ ------ 说明 end ------ ------ ------
forJava:
 Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$"); 
2) 固定电话:
 
--------------- 区号-号码 -------------------
String regex1 = "\\(?(010|021|022|023|024|025|026|027|028|029|852)?\\)?-?\\d{8}";//3位区号,8位号码
String regex2 = "\\(?(0[3-9][0-9]{2})?\\)?-?\\d{7,8}";//4位区号
String regex3 = "(\\(?(010|021|022|023|024|025|026|027|028|029|852)?\\)?-?\\d{8})|(\\(?(0[3-9][0-9]{2})?\\)?-?\\d{7,8})";
--------------- 加上分机号 (\\-?[0-9]{1,4})? ------- 区号-号码-分机号 ---------------
String regex1 = "\\(?(010|021|022|023|024|025|026|027|028|029|852|)\\)?-?\\d{8}(\\-?[0-9]{1,4})?";//3位区号
String regex2 = "\\(?(0[3-9][0-9]{2})\\)?-?\\d{7,8}(\\-?[0-9]{1,4})?";//4位区号
String regex3 = "(\\(?(010|021|022|023|024|025|026|027|028|029|852|)\\)?-?\\d{8}(\\-?[0-9]{1,4})?)|(\\(?(0[3-9][0-9]{2})\\)?-?\\d{7,8}(\\-?[0-9]{1,4})?)";

3. IP地址:

(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){3}
forJava:
 (25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)){3}

4. 邮箱:
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
forJava:
 p = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");

5. 日期:
------------- 年-月-日: ------------------
年:
//年份为四位,且不能是0000
([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})
月-日 //未考虑闰年.
((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))
年-月-日

Pattern.compile("([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))");//说明:
年份为四位,且不能是0000,之后是月日,未考虑闰年.

6. 中文:
[\u4e00-\u9fa5]
forJava:
 p = Pattern.compile("^[\u4e00-\u9fa5]+$");

======================== 说明 ==================
1.
\w
---> 单词字符[a-zA-Z_0-9],即Java中的标识符
\w+
---> 一个或多个单词字符[a-zA-Z_0-9]{1,}
2.
[-+.]
 ---> -或+或.
单个字符
3.
X*
---> 零次或多次
X?
---> 零次或一次
X+
---> 一次或多次
4.
需要转义的特殊字符: 
\
---> \\
[
---> \[
]
---> \]
(
---> \(
)
---> \)
{
---> \{
}
---> \}
.
---> \.
*
---> \*
?
---> \?
+
---> \+
^
---> \^
$
---> \$
|
---> \|
5. 常用正则表达式查询地址: http://www.ostools.net/regex#
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 正则表达式