java验证email的正则表达式式

博客访问: 1667174
博文数量: 446
博客积分: 7040
博客等级: 少将
技术积分: 4121
注册时间:
范德萨发而为
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Java
最大匹配模式
X?&&&&& X, once or not at all
X*&&&&&&&& X, zero or more times
X+&&&&&&&& X, one or more times
X{n}&&&&&&&& X, exactly n times
X{n,}&&&&&&&& X, at least n times
X{n,m}&&&&&&&& X, at least n but not more than m times
最小匹配模式&
X??&&&&&&&& X, once or not at all
X*?&&&&&&&& X, zero or more times
X+?&&&&&&&& X, one or more times
X{n}?&&&&&&&& X, exactly n times
X{n,}?&&&&&&&&&&&&X, at least n times
X{n,m}?&&&&&&&& X, at least n but not more than m times
正则表达式写过很多,javascript貌似默认为最小匹配的。一直不知道JAVA正则的最小匹配需要在后面加个?号。这里给自己做一下笔记。
本文出自 “” 博客,请务必保留此出处
阅读(2671) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。java中的正则表达式是数字校验 -
- ITeye博客
博客分类:
//正则表达式数字验证
&&& public boolean isNumber(String str)
&&& {
&&&&&&& java.util.regex.Pattern pattern=java.util.pile("[0-9]*");
&&&&&&& java.util.regex.Matcher match=pattern.matcher(str);
&&&&&&& if(match.matches()==false)
&&&&&&& {
&&&&&&&&&&&&
&&&&&&& }
&&&&&&& else
&&&&&&& {
&&&&&&&&&&&&
&&&&&&& }
&&& }
浏览: 6439 次
来自: 杭州Java - 正则表达式的运用(Pattern模式和Matcher匹配) - Josh_Persistence - ITeye博客
博客分类:
一、绪论:
在写程序的过程中,有时会需要匹配、查找、替换或者是判断字符串的出现情况,而且有时不能用简单的纯编码方式解决这些问题,这个时候就会想到要正则表达式,无论是Java, PHH, C#,
JavaScript, ActionScript, Perl等语言,都提高了强大的正则表达式支持,有的语言的精华就在于字符串处理功能比如Perl。
在Java中,正则表达式也是Java处理字符串,文本的重要工具。
Java对正则表达式的处理集中在以下两个类:
java.util.regex.Pattern
模式类:用来表示一个编译过的正则表达式。
java.util.regex.Matcher
匹配类:用模式匹配一个字符串所得到的结果。
二、先看一个简单的例子:
需求:从字符串:{"_type":"FQDN","_oid":"51a867eb1422ad"} 中取出这段数字:51a867eb1422ad
没有用过正则表达式的程序员可能分为两步获取
1. 用String类的indexOf方法获取51a867eb1422ad的初始位置
2. 用String类的subString方法取出51a867eb1422ad
用这种方法的缺点是代码可阅读性很差,即我们常说的hard code
如果用正则表达式则可以用以下的方法:
String reg = "[0-9A-Za-z]{24,}"; // appear at least 24 times ^[0-9A-Za-z]{24,}
Pattern pattern = pile(reg);
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {// matcher.matchers() {
String fqdnId = matcher.group();
三、一些常见的问题
锁定模式的应用范围的 ^ 和 $ 。他们是分别用来匹配字符串的开始和结束。
"^wangsheng": 开头一定要有"wangsheng"的字符串才能被匹配;
"isJoshWang$": 结尾一定要由"isJoshWang" 的字符串来结尾;
"^abc$": 就是要求以abc开头和以abc结尾的字符串,实际上是只有abc匹配。
"notice": 匹配包含notice的字符串。
用这两个字符就将模式锁定在一定范围里面。
2. Java对反斜线的处理问题:
在其他语言中,\\表示要插入一个字符\;
在Java语言中,\\表示要插入正则表达式的反斜线,并且后面的字符有特殊意义。
在Java正则表达式中,如果要插入一个\字符,则需要在正则表达式中写成\\\\,原因是APIDoc定义\\表示一个反斜线。
但是如果在正则表示式中表示回车换行等,则不需要多添加反斜线了。比如回车\r就写作\r.
3. 常用的与正则表达式相关的API
1) Matcher.find():尝试查找与模式匹配的字符序列的下一个子序列。此方法从字符序列的开头开始,如果该方法的前一次调用成功了并且从那时开始匹配器没有被重置,则从以前匹配操作没有匹配到的第一个字符开始,即如果前一次找到与模式匹配的子序列则这次从这个子序列后开始查找。
2) Matcher.matchers():判断整个字符序列与模式是否匹配。
当连续用Matcher对象检查多个字符串时候,可以使用Matcher.reset()重置匹配器,放弃其所有显式状态信息并将其添加位置设置为零。或者Matcher.reset(CharSequence input)
重置此具有新输入序列的匹配器来重复使用匹配器。
3) 组的概念,这个概念很重要,组是用括号划分的正则表达式,可以通过编号来引用组。组号从0开始,有几对小括号就表示有几个组,并且组可以嵌套,组号为0的表示整个表达式,组号为1的表示第一个组,依此类推。
例如:A(B)C(D)E正则式中有三组,组0是ABCDE,组1是B,组2是D;
A((B)C)(D)E正则式中有四组:组0是ABCDE,组1是BC,组2是B;组3是C,组4是D。
int groupCount():返回匹配其模式中组的数目,不包括第0组。
String group():返回前一次匹配操作(如find())的第0组。
String group(int group):返回前一次匹配操作期间指定的组所匹配的子序列。如果该匹配成功,但指定的组未能匹配字符序列的任何部分,则返回 null。
int start(int group):返回前一次匹配操作期间指定的组所匹配的子序列的初始索引。
int end(int group):返回前一次匹配操作期间指定的组所匹配的子序列的最后索引+1。
4)匹配的范围的控制
最变态的就要算lookingAt()方法了,名字很让人迷惑,需要认真看APIDoc。
返回以前匹配的初始索引。
返回最后匹配字符之后的偏移量。
public boolean lookingAt()尝试将从区域开头开始的输入序列与该模式匹配。
与 matches 方法类似,此方法始终从区域的开头开始;与之不同的是,它不需要匹配整个区域。
如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。
返回:当且仅当输入序列的前缀匹配此匹配器的模式时才返回 true。
5) Pattern标记
Pattern类的静态方法
static Pattern compile(String regex, int flags)
将给定的正则表达式编译到具有给定标志的模式中。
其中的flags参数就是Pattern标记,这个标记在某些时候非常重要。
Pattern.CANON_EQ
启用规范等价。
Pattern.CASE_INSENSITIVE
启用不区分大小写的匹配。
模式中允许空白和注释。
Pattern.DOTALL
启用 dotall 模式。
Pattern.LITERAL
启用模式的字面值分析。
Pattern.MULTILINE
启用多行模式。
Pattern.UNICODE_CASE
启用 Unicode 感知的大小写折叠。
Pattern.UNIX_LINES
启用 Unix 行模式。
4. 字符串的替换
String.replace(char oldChar, char newChar)
返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 而生成的。
String.replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串匹配字面值目标序列的每个子字符串。
String.replaceAll(String regex, String replacement)
使用给定的 replacement 字符串替换此字符串匹配给定的正则表达式的每个子字符串。
String.replaceFirst(String regex, String replacement)
使用给定的 replacement 字符串替换此字符串匹配给定的正则表达式的第一个子字符串。
StringBuffer.replace(int start, int end, String str)
使用给定 String 中的字符替换此序列的子字符串中的字符。
StringBuilder.replace(int, int, java.lang.String)
使用给定 String 中的字符替换此序列的子字符串中的字符。
Matcher.replaceAll(String replacement)
替换模式与给定替换字符串相匹配的输入序列的每个子序列。
Matcher.replaceFirst(String replacement)
替换模式与给定替换字符串匹配的输入序列的第一个子序列。
5、 字符串的切分
String[] split(String regex)
根据给定的正则表达式的匹配来拆分此字符串。
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串。
当然,还有一个StringTokenizer类,可以用来切分字符串,但是现在SUN已经不推荐使用了。转变下思路,其实用正则表达式也可以达到将字符串切分为段的目的。
6. 正则表达式最大的难点在于熟练书写正则表达式:
反斜线字符
带有八进制值 0 的字符 n (0 &= n &= 7)
带有八进制值 0 的字符 nn (0 &= n &= 7)
带有八进制值 0 的字符 mnn(0 &= m &= 3、0 &= n &= 7)
带有十六进制值 0x 的字符 hh
带有十六进制值 0x 的字符 hhhh
制表符 ('\u0009')
新行(换行)符 ('\u000A')
回车符 ('\u000D')
换页符 ('\u000C')
报警 (bell) 符 ('\u0007')
转义符 ('\u001B')
对应于 x 的控制符
a、b 或 c(简单类)
任何字符,除了 a、b 或 c(否定)
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](减去)
预定义字符类
任何字符(与可能匹配也可能不匹配)
数字:[0-9]
非数字: [^0-9]
空白字符:[ \t\n\x0B\f\r]
非空白字符:[^\s]
单词字符:[a-zA-Z_0-9]
非单词字符:[^\w]
POSIX 字符类(仅 US-ASCII)
小写字母字符:[a-z]
大写字母字符:[A-Z]
所有 ASCII:[\x00-\x7F]
字母字符:[\p{Lower}\p{Upper}]
十进制数字:[0-9]
字母数字字符:[\p{Alpha}\p{Digit}]
标点符号:!"#$%&'()*+,-./:;&=&?@[\]^_`{|}~
可见字符:[\p{Alnum}\p{Punct}]
可打印字符:[\p{Graph}\x20]
空格或制表符:[ \t]
控制字符:[\x00-\x1F\x7F]
\p{XDigit}
十六进制数字:[0-9a-fA-F]
空白字符:[ \t\n\x0B\f\r]
java.lang.Character 类(简单的 )
\p{javaLowerCase}
等效于 java.lang.Character.isLowerCase()
\p{javaUpperCase}
等效于 java.lang.Character.isUpperCase()
\p{javaWhitespace}
等效于 java.lang.Character.isWhitespace()
\p{javaMirrored}
等效于 java.lang.Character.isMirrored()
Unicode 块和类别的类
\p{InGreek}
Greek 块(简单)中的字符
大写字母(简单)
\P{InGreek}
所有字符,Greek 块中的除外(否定)
[\p{L}&&[^\p{Lu}]]
所有字母,大写字母除外(减去)
边界匹配器
非单词边界
输入的开头
上一个匹配的结尾
输入的结尾,仅用于最后的(如果有的话)
输入的结尾
Greedy 数量词
X,一次或一次也没有
X,零次或多次
X,一次或多次
X,恰好 n 次
X,至少 n 次
X,至少 n 次,但是不超过 m 次
Reluctant 数量词
X,一次或一次也没有
X,零次或多次
X,一次或多次
X,恰好 n 次
X,至少 n 次
X,至少 n 次,但是不超过 m 次
Possessive 数量词
X,一次或一次也没有
X,零次或多次
X,一次或多次
X,恰好 n 次
X,至少 n 次
X,至少 n 次,但是不超过 m 次
Logical 运算符
任何匹配的 nth
Nothing,但是引用以下字符
Nothing,但是引用所有字符,直到 \E
Nothing,但是结束从 \Q 开始的引用
特殊构造(非捕获)
X,作为非捕获组
(?idmsux-idmsux)
Nothing,但是将匹配标志
(?idmsux-idmsux:X)
X,作为带有给定标志
X,通过零宽度的正 lookahead
X,通过零宽度的负 lookahead
X,通过零宽度的正 lookbehind
X,通过零宽度的负 lookbehind
X,作为独立的非捕获组
反斜线、转义和引用
反斜线字符 ('\') 用于引用转义构造,如上表所定义的,同时还用于引用其他将被解释为非转义构造的字符。因此,表达式 \\ 与单个反斜线匹配,而 \{ 与左括号匹配。
在不表示转义构造的任何字母字符前使用反斜线都是错误的;它们是为将来扩展正则表达式语言保留的。可以在非字母字符前使用反斜线,不管该字符是否非转义构造的一部分。
的要求,Java 源代码的字符串中的反斜线被解释为 或其他。因此必须在字符串字面值中使用两个反斜线,表示正则表达式受到保护,不被 Java 字节码编译器解释。例如,当解释为正则表达式时,字符串字面值 "\b" 与单个退格字符匹配,而 "\\b" 与单词边界匹配。字符串字面值 "\(hello\)" 是非法的,将导致编译时错误;要与字符串 (hello) 匹配,必须使用字符串字面值 "\\(hello\\)"。
字符类可以出现在其他字符类中,并且可以包含并集运算符(隐式)和交集运算符 (&&)。并集运算符表示至少包含其某个操作数类中所有字符的类。交集运算符表示包含同时位于其两个操作数类中所有字符的类。
字符类运算符的优先级如下所示,按从最高到最低的顺序排列:
字面值转义
[a-e][i-u]
[a-z&&[aeiou]]
注意,元字符的不同集合实际上位于字符类的内部,而非字符类的外部。例如,正则表达式 . 在字符类内部就失去了其特殊意义,而表达式 - 变成了形成元字符的范围。
行结束符 是一个或两个字符的序列,标记输入字符序列的行结尾。以下代码被识别为行结束符:
新行(换行)符 ('\n')、
后面紧跟新行符的回车符 ("\r\n")、
单独的回车符 ('\r')、
下一行字符 ('\u0085')、
行分隔符 ('\u2028') 或
段落分隔符 ('\u2029)。
模式,则新行符是唯一识别的行结束符。
如果未指定
标志,则正则表达式 . 可以与任何字符(行结束符除外)匹配。
默认情况下,正则表达式 ^ 和 $ 忽略行结束符,仅分别与整个输入序列的开头和结尾匹配。如果激活
模式,则 ^ 在输入的开头和行结束符之后(输入的结尾)才发生匹配。处于
模式中时,$ 仅在行结束符之前或输入序列的结尾处匹配。
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
((A)(B(C)))
组零始终代表整个表达式。
之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back 引用在表达式中使用,也可以在匹配操作完成后从匹配器获取。
与组关联的捕获输入始终是与组最近匹配的子序列。如果由于量化的缘故再次计算了组,则在第二次计算失败时将保留其以前捕获的值(如果有的话)例如,将字符串 "aba" 与表达式 (a(b)?)+ 相匹配,会将第二组设置为 "b"。在每个匹配的开头,所有捕获的输入都会被丢弃。
以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数。
Unicode 支持
第 1 级和 RL2.1 Canonical Equivalents。
Java 源代码中的 Unicode 转义序列(如 \u2014)是按照 Java Language Specification 的 中的描述处理的。这样的转义序列还可以由正则表达式解析器直接实现,以便在从文件或键盘击键读取的表达式中使用 Unicode 转义。因此,可以将不相等的字符串 "\u2014" 和 "\\u2014" 编译为相同的模式,从而与带有十六进制值 0x2014 的字符匹配。
与 Perl 中一样,Unicode 块和类别是使用 \p 和 \P 构造编写的。如果输入具有属性 prop,则与 \p{prop} 匹配,而输入具有该属性时与 \P{prop} 不匹配。块使用前缀 In 指定,与在 InMongolian 中一样。可以使用可选前缀 Is 指定类别:\p{L} 和 \p{IsL} 都表示 Unicode 字母的类别。块和类别在字符类的内部和外部都可以使用。
受支持的类别是由
类指定版本中的
的类别。类别名称是在 Standard 中定义的,即标准又丰富。Pattern 所支持的块名称是
所接受和定义的有效块名称。
行为类似 java.lang.Character boolean 是 methodname 方法(废弃的类别除外)的类别,可以通过相同的 \p{prop} 语法来提供,其中指定的属性具有名称 javamethodname。
与 Perl 5 相比较
Pattern 引擎用有序替换项执行传统上基于 NFA 的匹配,与 Perl 5 中进行的相同。
此类不支持 Perl 构造:
条件构造 (?{X}) 和 (?(condition)X|Y)、
嵌入式代码构造 (?{code}) 和 (??{code})、
嵌入式注释语法 (?#comment) 和
预处理操作 \l \u、\L 和 \U。
此类支持但 Perl 不支持的构造:
Possessive 数量词,它可以尽可能多地进行匹配,即使这样做导致所有匹配都成功时也如此。
字符类并集和交集,如所述。
与 Perl 的显著不同点是:
在 Perl 中,\1 到 \9 始终被解释为 Back 引用;如果至少存在多个子表达式,则大于 9 的反斜线转义数按 Back 引用对待,否则在可能的情况下,它将被解释为八进制转义。在此类中,八进制转义必须始终以零开头。在此类中,\1 到 \9 始终被解释为 Back 引用,较大的数被接受为 Back 引用,如果在正则表达式中至少存在多个子表达式的话;否则,解析器将删除数字,直到该数小于等于组的现有数或者其为一个数字。
Perl 使用 g 标志请求恢复最后匹配丢失的匹配。此功能是由
类显式提供的:重复执行
方法调用可以恢复丢失的最后匹配,除非匹配器被重置。
在 Perl 中,位于表达式顶级的嵌入式标记对整个表达式都有影响。在此类中,嵌入式标志始终在它们出现的时候才起作用,不管它们位于顶级还是组中;在后一种情况下,与在 Perl 中类似,标志在组的结尾处还原。
Perl 允许错误匹配构造,如在表达式 *a 中,以及不匹配的括号,如在在表达式 abc] 中,并将其作为字面值对待。此类还接受不匹配的括号,但对 +、? 和 * 不匹配元字符有严格限制;如果遇到它们,则抛出 。
有关正则表达式构造行为更准确的描述,请参见 ,该书由 Jeffrey E. F. Friedl、O'Reilly 和 Associates 合著,于 2002 年出版。
浏览 24025
Josh_Persistence
浏览: 782486 次
来自: 上海
VCenter、ESXServer、Cluster这些实体类在 ...
感谢楼主分享
感觉博主的图有点问题吧~觉得暂存区到工作区应该是git res ...
这两天正在学习solrcloud,相当受用。发现solrclo ...
請教一下:1&我的Solr安裝在d:\solr-5.4. ...Java正则表达式学习(二) - 向上吧,少年! - ITeye博客
博客分类:
7.量词(Quantifiers)匹配
Java正则表达式中的Quantifiers(量词)是用来指定匹配字符出现的次数的,java api 中有三种Quantifiers:greedy,reluctant and possessive.虽然三种quantifiers的作用很相似,但是三者还是有区别的
(reluctant)
(possessive)
匹配 X 零次或一次
匹配 X 零次或多次
匹配 X 一次或多次
匹配 X n 次
匹配 X 至少 n 次
匹配 X 至少 n 次,但不多于 m 次
我们现在就从贪婪(greedy)词开始,构建三个不同的正则表达式:字母a后面跟着?、*和+。接下来看一下,用这些表达式来测试输入的字符串是空字符串时会发生些什么:
Enter your regex: a?
Enter input string to search:
I found the text "" starting at index 0 and ending at index 0.
Enter your regex: a*
Enter input string to search:
I found the text "" starting at index 0 and ending at index 0.
Enter your regex: a+
Enter input string to search:
No match found.
7.1 零长度匹配
在上面的例子中,开始的两个匹配时成功的,这是因为表达式a?和a*都允许字符出现零次。就目前而言,这个例子不像其它的,也许你注意到了开始索引和结束索引都是0。输入的空字符串没有长度,因此该测试简单地在索引0上匹配什么都没有,诸如此类的匹配称之为零上都匹配(zero-length matches).零长度匹配会出现在以下几种情况:输入空的字符串、在输入字符串的开始处、在输入字符串最后字符的后面,或者是输入字符串任意两个字符之间。由于它们开始和结束的位置有着相同的索引,因此零长度匹配是很容易被发现的。
我们来看一下关于零长度匹配更多的例子。把输入的字符串改成单个字符"a",你是否注意到一些有意思的事情:
Enter your regex: a?
Enter input string to search: a
I found the text "a" starting at index 0 and ending at index 1.
I found the text "" starting at index 1 and ending at index 1.
Enter your regex: a*
Enter input string to search: a
I found the text "a" starting at index 0 and ending at index 1.
I found the text "" starting at index 1 and ending at index 1.
Enter your regex: a+
Enter input string to search: a
I found the text "a" starting at index 0 and ending at index 1.
所有的三个量词都是用来寻找字母"a"的,但是前面两个在索引1处找到了零长度匹配,也就是说,在输入字符串最后一个字符的后面。回想一下,匹配把字符"a"看作是位于索引0和索引1之间的单元格中,并且测试工具一支循环下去直到不再有匹配为止。依赖与所使用的量词不同,最后字符后面的索引"什么也没有"的存在可以或者不可以触发一个匹配。
现在把输入的字符串改成一行5个"a"时,会得到下面的结果:
Enter your regex: a?
Enter input string to search: aaaaa
I found the text "a" starting at index 0 and ending at index 1.
I found the text "a" starting at index 1 and ending at index 2.
I found the text "a" starting at index 2 and ending at index 3.
I found the text "a" starting at index 3 and ending at index 4.
I found the text "a" starting at index 4 and ending at index 5.
I found the text "" starting at index 5 and ending at index 5.
Enter your regex: a*
Enter input string to search: aaaaa
I found the text "aaaaa" starting at index 0 and ending at index 5.
I found the text "" starting at index 5 and ending at index 5.
Enter your regex: a+
Enter input string to search: aaaaa
I found the text "aaaaa" starting at index 0 and ending at index 5.
在"a"出现零次或一次时,表达式a?寻找到所匹配的的每一个字符。
表达式a*找到两个单独的匹配:第一次匹配到所有的字母"a",然后是匹配到最后一个字符后面的索引5。
最后,a+匹配了所有出现的字母"a",忽略了在最后索引处"什么都没有"的存在。
在这里,你也许会感到疑惑,开始的两个量词在遇到除了"a"的字母时会有什么结果。例如,在"ababaaaab"中遇到字母"b"会发生什么呢?
下面我们来看一下:
Enter your regex: a?
Enter input string to search: ababaaaab
I found the text "a" starting at index 0 and ending at index 1.
I found the text "" starting at index 1 and ending at index 1.
I found the text "a" starting at index 2 and ending at index 3.
I found the text "" starting at index 3 and ending at index 3.
I found the text "a" starting at index 4 and ending at index 5.
I found the text "a" starting at index 5 and ending at index 6.
I found the text "a" starting at index 6 and ending at index 7.
I found the text "a" starting at index 7 and ending at index 8.
I found the text "" starting at index 8 and ending at index 8.
I found the text "" starting at index 9 and ending at index 9.
Enter your regex: a*
Enter input string to search: ababaaaab
I found the text "a" starting at index 0 and ending at index 1.
I found the text "" starting at index 1 and ending at index 1.
I found the text "a" starting at index 2 and ending at index 3.
I found the text "" starting at index 3 and ending at index 3.
I found the text "aaaa" starting at index 4 and ending at index 8.
I found the text "" starting at index 8 and ending at index 8.
I found the text "" starting at index 9 and ending at index 9.
Enter your regex: a+
Enter input string to search: ababaaaab
I found the text "a" starting at index 0 and ending at index 1.
I found the text "a" starting at index 2 and ending at index 3.
I found the text "aaaa" starting at index 4 and ending at index 8.
即使字母"b"在单元格1、3、8中出现,但在这些位置上的输出报告了零长度匹配。正则表达式a?不是特意地去寻找字母"b",它仅仅是去找字母"a"存在或者其中缺少的。如果量词允许匹配"a"零次,任何输入的字符不是"a"时将会作为零长度匹配。在前面的例子中,根据讨论的规则保证了a被匹配。
对于要精确地匹配一个模式n次时,可以简单地在一对花括号内指定一个数值:
Enter your regex: a{3}
Enter input string to search: aa
No match found.
Enter your regex: a{3}
Enter input string to search: aaa
I found the text "aaa" starting at index 0 and ending at index 3.
Enter your regex: a{3}
Enter input string to search: aaaa
I found the text "aaa" starting at index 0 and ending at index 3.
这里,正则表达式a{3}在一行中寻找连续出现三次的字母"a".第一次测试失败的原因在于,输入的字符串没有足够的a用来匹配;第二次测试输入的字符串正好包括三个"a",触发了一次匹配;第三次测试也触发了一次匹配,这是由于在输出的字符串的开始部分正好有三个"a".接下来的事情与第一次的匹配时不相关的,如果这个模式将在这一点后继续出现,那它将会触发接下来的匹配:
Enter your regex: a{3}
Enter input string to search: aaaaaaaaa
I found the text "aaa" starting at index 0 and ending at index 3.
I found the text "aaa" starting at index 3 and ending at index 6.
I found the text "aaa" starting at index 6 and ending at index 9.
对于需要一个模式出现至少n次时,可以在这个数字后面加上一个逗号(,):
Enter your regex: a{3,}
Enter input string to search: aaaaaaaaa
I found the text "aaaaaaaaa" starting at index 0 and ending at index 9.
输入一样的字符串,这次测试仅仅找到了一个匹配,这是由于一个中有九个"a"满足了"至少"三个"a"的要求。
最后,对于指定出现次数的上限,可以在花括号添加第二个数字。
Enter your regex: a{3,6}
//寻找一行中至少连续出现3个(但不多于6个)"a"
Enter input string to search: aaaaaaaaa
I found the text "aaaaaa" starting at index 0 and ending at index 6.
I found the text "aaa" starting at index 6 and ending at index 9.
这里,第一次匹配在6个字符的上限时被迫终止了。第二个匹配包括了剩余的三个a(这是匹配所允许最小的字符个数)。如果输入的字符串在少掉一个字母,这里将不会有第二个匹配,之后仅剩余两个a。
7.2 捕获组和字符类中的量词
到目前为止,仅仅测试了输入的字符串包括一个字符的量词。实际上,量词仅仅可能附在一个字符后面一次,因此正则表达式abc+的意思就是"a后面接着b,在接着一次或多次的c",它的意思并不是指abc一次或多次。然而,量词也可能附在字符类和捕获组的后面,比如,[abc]+表示一次或多次的a或b或c,(abc)+表示一次或者多次的"abc"组。
我们来指定(dog)组在一行中三次进行说明。
Enter your regex: (dog){3}
Enter input string to search: dogdogdogdogdogdog
I found the text "dogdogdog" starting at index 0 and ending at index 9.
I found the text "dogdogdog" starting at index 9 and ending at index 18.
Enter your regex: dog{3}
Enter input string to search: dogdogdogdogdogdog
No match found.
上面的第一个例子找到了三个匹配,这是由于量词用在了整个捕获组上。然后,把圆括号去掉,这时的量词{3}现在仅用在了字母"g"上,从而导致这个匹配失败。
类似地,也能把量词应用于整个字符类:
Enter your regex: [abc]{3}
Enter input string to search: abccabaaaccbbbc
I found the text "abc" starting at index 0 and ending at index 3.
I found the text "cab" starting at index 3 and ending at index 6.
I found the text "aaa" starting at index 6 and ending at index 9.
I found the text "ccb" starting at index 9 and ending at index 12.
I found the text "bbc" starting at index 12 and ending at index 15.
Enter your regex: abc{3}
Enter input string to search: abccabaaaccbbbc
No match found.
上面的第一个例子中,量词{3}应用在整个字符类上,但是第二个例子这个量词仅用在字母"c"上。
7.3 贪婪、勉强和侵占量词间的不同
在贪婪、勉强和侵占三个量词间有着细微的不同。
贪婪量词之所以称之为"贪婪的",是由于它们强迫匹配器读入(或者称之为吃掉)整个输入的字符串,来优先尝试第一次匹配,如果第一次尝试匹配(对整个输入的字符串)失败,匹配器会通过回退整个字符串的一个字符再一次进行尝试,不断的进行处理直到找到一个匹配,或者左边没有更多的字符用来回退了。赖于在表达式中使用的量词,最终它将尝试地靠着1或0个字符的匹配。
但是,勉强量词采用相反的路径:从输入字符串的开始处开始,因此每次勉强地吞噬一个字符来寻找匹配,最终它们尝试整个输入的字符串。
最后,侵占量词始终是吞掉整个输入的字符串,尝试着一次(仅有一次)匹配。不像贪婪量词那样,侵占量词绝不会回退,即使这样是允许全部的匹配成功。
为了说明一下,看看输入的字符串是xfooxxxxxxfoo时。
Enter your regex: .*foo
//贪婪量词
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.
Enter your regex: .*?foo
//勉强量词
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.
Enter your regex: .*+foo
//侵占量词
Enter input string to search: xfooxxxxxxfoo
No match found.
第一个例子使用贪婪量词.*,寻找紧跟着字母"f" "o" "o" 的"任何东西"零次或者多次。由于量词是贪婪的,表达式的.*部分第一次"吃掉"整个输入的字符串。在这一点,全部表达式不能成功地进行匹配,这是由于最后三个字母("f" "o" "o")已经被消耗掉了。那么匹配器会慢慢地每次回退一个字母,直到返还的"foo"在最右边出现,这时匹配成功并且搜索终止。
然而,第二个例子采用勉强量词,因此通过首次消耗"什么也没有"作为开始。由于"foo"并没有出现在字符串的开始,它被强迫吞掉第一个字母("x"),在0和4处触发了第一个匹配。测试工具会继续处理,直到输入的字符串耗尽位置。在4和13找到了另外一个匹配。
第三个例子的量词是侵占,所以在寻找匹配时失败,在这种情况下,整个输入的字符串被 .*+消耗了,什么都没有剩下来满足表达式末尾的"foo"。
你可以在想抓取所有的东西,且绝不回退的情况下使用侵占量词,在这种匹配不是立即被发现的情况下,它将会优于等价的贪婪量词。
浏览: 176834 次
来自: 上海
你好,我运行到第四步,添加表视图及其数据,但最后表格数据没有显 ...
@bugcn 客气客气,我也是照着别人写的例子,然后边做边写。 ...
顶一个,这样的教程对我这样的初学者太有用了,博主辛苦啦}

我要回帖

更多关于 正则表达式() 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信