正则表达式(Regular Expression)
来源:互联网 发布:医院的信息化建设网络 编辑:程序博客网 时间:2024/06/05 11:46
正则表达式(Regular Expression)
正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE)。
正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。
元字符
n
”匹配字符“n
”。“\n
”匹配一个换行符。序列“\\
”匹配“\
”而“\(
”则匹配“(
”。\n
”之外的任何单个字符。要匹配包括“\n
”在内的任何字符,请使用像“(.|\n)
”的模式。例如:a.c
匹配abc,而[.|\n]*
则匹配任意字符z|food
”能匹配“z
”或“food
”。“(z|f)ood
”则匹配“zood
”或“food
”。[abc]
”可以匹配“plain
”中的“a
”。[^abc]
”可以匹配“plain
”中的“p
”“l
”“i
”“n
”。[a-z]
”可以匹配“a
”到“z
”范围内的任意小写字母字符。[^a-z]
”可以匹配任何不在“a
”到“z
”范围内的任意字符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“
c
”字符。例如:\cM匹配一个Control-M或回车符。\x41
”匹配“A
”。“\x041
”则等价于“\x04&1
”。(.)\1
”匹配两个连续的相同字符。
量词(用在字符或()之后)
z
”、“zo
”以及“zoo
”。*等价于{0,}。zo+
”能匹配“zo
”以及“zoo
”,但不能匹配“z
”。+等价于{1,}。do(es)?
”可以匹配“do
”或“does
”中的“do
”。?等价于{0,1}。o{2}
”不能匹配“Bob
”中的“o
”,但是能匹配“food
”中的两个o。o{2,}
”不能匹配“Bob
”中的“o
”,但能匹配“foooood
”中的所有o。“o{1,}
”等价于“o+
”。“o{0,}
”则等价于“o*
”。o{1,3}
”将匹配“fooooood
”中的前三个o。“o{0,1}
”等价于“o?
”。请注意在逗号和两个数之间不能有空格。oooo
”,“o+?
”将匹配单个“o
”,而“o+
”将匹配所有“o
”。
边界匹配
\n
”或“\r
”之后的位置。例如:^\d{3} 与搜索字符串开始处的 3 个数字匹配。\n
”或“\r
”之前的位置。例如:\d{3}$ 与搜索字符串结尾处的 3 个数字匹配。(?
例如:“er\b
”可以匹配“never
”中的“er
”,但不能匹配“verb
”中的“er
”。er\B
”能匹配“verb
”中的“er
”,但不能匹配“never
”中的“er
”。\Aabc
”能匹配“abcdef
”中的“abc
”,但不能匹配“aabcd
”中的“abc
”。def\z
”能匹配“abcdef
”中的“def
”,但不能匹配“defdefabc
”中的“def
”。
分组语法
\(
”或“\)
”。详细见后面分组与后向引用。例如:\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 或者kitty kitty。\1则代表了前面()捕捉到的字符串(|)
”来组合一个模式的各个部分是很有用。例如:“industr(?:y|ies)
”就是一个比“industry|industries
”更简略的表达式。Windows(?=95|98|NT|2000)
”能匹配“Windows2000
”中的“Windows
”,但不能匹配“Windows3.1
”中的“Windows
”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。Windows(?!95|98|NT|2000)
”能匹配“Windows3.1
”中的“Windows
”,但不能匹配“Windows2000
”中的“Windows
”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始Windows(?!95|98|NT|2000)
”能匹配“Windows3.1
”中的“Windows
”,但不能匹配“Windows2000
”中的“Windows
”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始(?<!95|98|NT|2000)Windows
”能匹配“3.1Windows
”中的“Windows
”,但不能匹配“2000Windows
”中的“Windows
”。
预定义字符集(可以写在字符集[...]中)
实际上:在支持ASCII码的语言中,如JavaScript,“\w”等价于“
[A-Za-z0-9_]
”;在支持Unicode的语言中,如.NET,默认情况下,“\w”除可以匹配
[a-zA-Z0-9_]
外,还可以匹配一些Unicode字符集,如汉字,全角数字等等。几乎所有常见的语言都遵循这样一个规律,只有Java是个例外。等价于“
[A-Za-z0-9_]
”。[^A-Za-z0-9_]
”。
不可打印字符
优先级
注释
括号的另一种用途是通过语法(?#comment)来包含注释。
例如:2[0-4]\d(?#200-249)|250-5|[01]?\d\d?(?#0-199)。
其他
分组与后向引用
使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。
默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。
后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本。(不同语言可能表达不大一样)
- 分组0对应整个正则表达式
- 实际上组号分配过程是要从左向右扫描两遍的:第一遍只给未命名组分配,第二遍只给命名组分配--因此所有命名组的组号都大于未命名的组号
例如:
\b(\w+)\b\s+\1\b
可以用来匹配重复的单词,像go go, 或者kitty kitty。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b)
,这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+)
,最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)
。
也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)
(或者把尖括号换成'也行:(?'Word'\w+)
),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>
,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b
。
Note:不同语言也许语法上会有些许出入。
\w
的范围
在支持ASCII码的语言中,如JavaScript,“\w
”等价于[a-zA-Z0-9_]
;
在支持Unicode的语言中,如.NET,默认情况下,“\w
”除可以匹配[a-zA-Z0-9_]
外,还可以匹配一些Unicode字符集,如汉字,全角数字等等。
几乎所有常见的语言都遵循这样一个规律,只有Java是个例外。在Java中,“\w
”的表现是比较奇怪的,Java是支持Unicode的,但Java的正则中的“\w
”却是等价于[a-zA-Z0-9_]
的。
先来看一下“\w
”在几种语言中匹配的例子
Javascript:
<script language="javascript"> var str = "abc_123中文_d3=efg汉字%"; var reg = /\w+/g; var arr = str.match(reg); if(arr != null) { for(var i=0;i<arr.length;i++) { document.write(arr[i] + "<br />"); } }</script>/*-------- JavaScript中输出--------abc_123_d3Efg*/
C#:
string test = "abc_123中文_d3=efg汉字%";MatchCollection mc = Regex.Matches(test, @"\w+");foreach (Match m in mc){ richTextBox2.Text += m.Value + "\n";}/*-------- C#中输出--------abc_123中文_d3efg汉字*/
Java:
String test = "abc_123中文_d3=efg汉字%";String reg = "\\w+";Matcher m = Pattern.compile(reg).matcher(test);while(m.find()){ System.out.println(m.group());}/*-------- Java中输出--------abc_123_d3Efg*/
可以看到,“\w”在Java中的输出和JavaScript中是一样的,都是只支持ASCII字符。
\b
的范围
\b
见语言中“\w
”的范围确定了,那么是不是可以认为“\b
”的匹配范围与“\w
”也是一致的呢?再看下下面的例子:
源字符串:abc_123中文_d3=汉字efg
正则表达式:.\b
.
JavaScript:
<script language="javascript"> var str = "abc_123中文_d3=efg汉字%"; var reg = /.\b./g; var arr = str.match(reg); if(arr != null) { for(var i=0;i<arr.length;i++) { document.write(arr[i] + "<br />"); } }</script>/*-------- JavaScript中输出--------3中文_3=g汉*/
C#:
string test = "abc_123中文_d3=efg汉字%";MatchCollection mc = Regex.Matches(test, @".\b.");foreach (Match m in mc){ richTextBox2.Text += m.Value + "\n";}/*-------- C#中输出--------3=字%*/
Java:
String test = "abc_123中文_d3=efg汉字%";String reg = ".\\b.";Matcher m = Pattern.compile(reg).matcher(test);while(m.find()){ System.out.println(m.group());}/*-------- Java中输出--------3=字%*/
可以看到,Java的输出和.NET是一致的,“\b
”在Java中是支持Unicode的。
Note:“\b
”用在正则中,通常情况下都是表示单词边界的,只有在字符组中,它表示的是退格键。
如:即[a-z\b]
此处的“\b
”表示的是退格键,而不是单词边界。
所以总的来说,Java中的“\w
”是很奇怪的,而“\b
”是与其它语言表现一致的,在使用时需要注意。
转载请注明来自: blog.csdn.net/epluguo
附:
在线正则表达式验证器:
https://www.debuggex.com
https://mengzhuo.org/regex/
参考:
http://en.wikipedia.org/wiki/Regularexpression#citenote-PerlBestPractices-33
http://www.greenend.org.uk/rjk/tech/regexp.html
http://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F
http://msdn.microsoft.com/zh-cn/library/ae5bf541(v=vs.100).aspx
http://deerchao.net/tutorials/regex/regex.htm
http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
- 正则表达式(regular expression)
- 正则表达式(regular expression)
- 正则表达式(Regular Expression)
- 正则表达式(regular expression)
- 正则表达式 regular-expression
- 正则表达式(regular expression)
- 正则表达式(regular expression)
- 正则表达式(regular expression)
- 正则表达式(regular expression)
- 正则表达式(regular expression)
- 正则表达式(regular expression)
- 正则表达式(regular expression)
- 正则表达式(regular expression)
- 正则表达式(regular expression)
- 正则表达式,Regular Expression
- 正则表达式-Regular Expression
- 正则表达式 (Regular Expression)
- 正则表达式 Regular Expression
- 指针函数与函数指针的区别
- Write operations are not allowed in read-only mode (FlushMode.MANUAL):
- lua学习之旅2--学习笔记
- 全志行车记录仪里面FireEyepublic.apk反编译的分析(五)——图片存储
- 用户中心表和用户表的设计
- 正则表达式(Regular Expression)
- xxxHive-2-其他总结
- 转载:使用 mechanize 和 BeautifulSoup 收集 Web 数据
- IIS6.0应用程序池回收设置分析
- 通过ucenter整合discuz和phpcms,在discuz修改用户密码,ucenter通知失败,phpcms无法同步更新密码
- 实现lua 字符串spllit功能
- windowserver2008更换密钥方法
- 迭代器模式
- 反序列化无法找到程序集