【总结】关于(C#和Python中的)正则表达式
来源:互联网 发布:如何修改mysql字符集 编辑:程序博客网 时间:2024/05/22 07:09
http://www.crifan.com/summary_regular_expression_csharp_python/
此处总结一下,关于正则表达式的相关知识。
此文目的是总结一下正则表达式的基本语法,以及总结个人接触过的一些不同语言的实现中需要注意的地方,以及相关经验。
【正则表达式的最简介】
正则表达式,英文叫做Regular Expression,一般缩写为regex或regexp。
正则表达式,简单说,就是一组规则,用于实现字符串的查找,匹配,以实现关于字符串的相关操作,比如替换,删除等。
很多语言目前都已实现了对应的正则表达式的支持。
目前个人已知的有,Python脚本语言,C#语言,PHP语言,Notepad++软件的查找/替换功能中。
学会了正则表达式后,很多常见的文字,字符串的处理,就简单的多了,或者可以更加高效地实现功能,实现更加复杂的操作了。
【正则表达式的基本规则】
下面的规则,是从Python的说明文档中翻译过来的。
网上也有类似的总结,此处只是觉得这个解释更全,更精确,所以采用这部分的内容为基准。
其他不同语言所实现的正则表达式,语法上,也许个别会有不同,但是基本语法和含义,都是通用的。
下表,以供借鉴。
字符匹配的规则:
特殊字符等价于含义解释提示. 表示任意字符(除了换行符\n以外的任意单个字符) ^ 表示字符串的开始 $ 表示字符串行末或换行符之前 *{0,无穷多个}0或多个前面出现的正则表达式贪婪原则,即尽量匹配尽可能多个+{1,无穷多个}1或多个前面出现的正则表达式贪婪原则,即尽量匹配尽可能多个?{0,1}0或1个前面出现的正则表达式贪婪原则,即尽量匹配尽可能多个*?,+?,?? 使*,+,?尽可能少的匹配最少原则{m} 匹配m个前面出现的正则表达式 {m,n} 匹配最少m个,最多n个前面出现的正则表达式贪婪原则,即尽量匹配尽可能多个{m,n}? 匹配最少m个,最多n个前面前出现的最少原则\ 后接那些特殊字符,表示该字符;或者后接已经定义好的特殊含义的序列对于已经定义好的特殊序列,下面会详细解释。[] 指定所要匹配的字符集,可以列出单个字符;或者是一个字符范围,起始和结束字符之间用短横线-分割; | A|B,其中A和B可以是任意正则表达式,其中也支持更多的抑或A|B|C|… (……) 匹配括号内的字符串实现分组功能,用于后期获得对应不同分组中的字符串
已定义的字符序列的含义:
特殊序列/已定义的字符含义等价于含义解释提示\数字 表示前面用括号()括起来的某个组group \A 表示字符串的开始 \b 匹配空字符,但只是一个单词word的开始或者结束的空字符 \B\b含义取反匹配空字符,但只是,一个单词word的,除了开始或者结束位置的,的空字符 \d[0-9]匹配单个数字(0到9中的某个数字) \D[0-9]的取反非数字的单个字符,即除了0-9之外的任意单个字符 \s[ \t\n\r\f\v]匹配单个空白字符,包括空格,水平制表符\t,回车\r,换行\n,换页\f,垂直制表符\v \S\s的含义取反匹配非空白字符之外的单个字符 \w[a-zA-Z0-9_]匹配单个的任何字符,数字,下划线 \W\w的含义取反匹配单个的,非字母数字下划线之外的字符 \Z 匹配字符串的末尾
【一些总结和注意事项】
1.关于贪婪原则和最少原则
星号*,加号+,问号?,{m,n},都是属于贪婪原则,即在满足这些条件的情况下,尽可能地匹配多个。
而对应的后面加上一个问号?,变成:
*?, +?, ??, {m,n}?就变成了最少原则,即,在满足前面的条件的情况下,尽量少地匹配。
其中??,个人很少用。
而最常用的是 .+?,表示任意字符,最少是1个,然后后面匹配尽量少的所出现的字符。
2.反斜杠\
在正则表达式中,反斜杠\后面接一些特殊字符,表示该特殊字符,这些特殊是,上面所说过的:
.,^,$,*,+,?
对应的是:
\.,\^,\$,\*,\+,\?
以及反斜杠自己:
\\
其中如果是在中括号[]内,反斜杠加上对应的中括号[]和短横线-,即:
\[,\],\-
分别表示对应的字符本身。
3.上尖括号^
在中括号之外,表示字符的开始;
在中括号之内,表示取反,比如常见的[^0-9]
比如[^5]表示除了数字5之外的所有字符。
尤其特别的是[^^]表示除了上尖括号字符本身之外的所有字符。
4. 中括号内的+,*,(,)
中括号内的加号+,星号*,括号(,)表示对应字符本身,就不是特殊字符了。
【正则表达式的特点】
- 入门相对不难,但是能熟练,高效的利用其功能,还是不容易的。
【Python中的正则表达式:re模块】
优点:
1.python中字符串的表示,单引号和双引号,都是支持的。
所以对于字符串中,有双引号的,可以在写字符串最外层用单引号括起来,而不需要用反斜杠了。
反之,如果需要表示的其中包括单引号,那么最外层用双引号,所以,还是很方便的。
2.对于匹配多个字符串的时候,好像不能加括号分组的,如果加括号分组了,那么只能匹配单个一个group就结束了。对应的要匹配多个字符串,好像只能使用findall。
这部分内容,有空再好好总结一下。
【C#中的正则表达式:Regex类】
后来找到了,微软官方关于正则表达式知识的介绍,其中就有常用缩写所表示的含义:
Character Classes
优点:
1.可以一次性的即搜索多个匹配的整个的字符串,同时又可以一次性地,对于每个字符串,在给定Regex的时候,就分组group,然后得到macthes之后,foreach处理每个match,已经可以得到对应的匹配的结果,可以使用不同group的值了。还是很方便的。
注意事项:
1.正则表达式,是用字符串前面加上@字符来表示的。
2.双引号‘“’这个符号的表示是用两个双引号。
由于C#中本身字符串是双引号表示的,所以正则表达式中的双引号,就特殊了,是需要用两个双引号,表示对应的双引号这个字符的,而不是反斜杠加上双引号来表示双引号这个字符,这点,觉得还是很特殊的,需要注意一下。
关于C#中的Regex使用心得和注意事项,感兴趣的可以去看:
【总结】C#中的Regex的使用心得和注意事项
【C#和Python中关于正则表达式方面的对比】
1. 带名字的group
python和C#中的正则表达式,都支持带名字的group,即named group,关于具体的语法,两者有些微的区别:
Python: (?P<groupName>xxx)
C#: (?<groupName>xxx)
即Python中,named group的语法,比C#中,多了个P字母作为开头。
2.正则表达式字符串的开头标记字母
Python:r,比如r“(.+?)”
C#:@,比如@“(.+?)”
3.关于引用已捕获的带名字的组(back reference named group)
正则表达式的逻辑中,支持在写模式字符串中,引用前面已经过通过括号括起来的,带名字的组。
Python中的语法是:
C#中的语法是:
直接给出示例代码:
Python中关于引用named group的用法示例(记得要import re;):
#------------------------------------------------------------------------------
def
testBackReference():
# back reference (?P=name) test
backrefValidStr
=
'"group":0,"iconType":"NonEmptyDocumentFolder","id":"9A8B8BF501A38A36!601","itemType":32,"name":"released","ownerCid":"9A8B8BF501A38A36"'
;
backrefInvalidStr
=
'"group":0,"iconType":"NonEmptyDocumentFolder","id":"9A8B8BF501A38A36!601","itemType":32,"name":"released","ownerCid":"987654321ABCDEFG"'
;
backrefP
=
r
'"group":\d+,"iconType":"\w+","id":"(?P<userId>\w+)!\d+","itemType":\d+,"name":".+?","ownerCid":"(?P=userId)"'
userId
=
"";
foundBackref
=
re.search(backrefP, backrefValidStr);
print
"foundBackref="
,foundBackref;
# foundBackref= <_sre.SRE_Match object at 0x02B96660>
if
(foundBackref):
userId
=
foundBackref.group(
"userId"
);
print
"userId="
,userId;
# userId= 9A8B8BF501A38A36
print
"can found userId here"
;
foundBackref
=
re.search(backrefP, backrefInvalidStr);
print
"foundBackref="
,foundBackref;
# foundBackref= None
if
(
not
foundBackref):
print
"can NOT found userId here"
;
return
;
C#关于引用named group的示例代码(记得要using System.Text.RegularExpressions;):
void
testBackReference()
{
// back reference \k<name> test
string
backrefValidStr =
"\"group\":0,\"iconType\":\"NonEmptyDocumentFolder\",\"id\":\"9A8B8BF501A38A36!601\",\"itemType\":32,\"name\":\"released\",\"ownerCid\":\"9A8B8BF501A38A36\""
;
string
backrefInvalidStr =
"\"group\":0,\"iconType\":\"NonEmptyDocumentFolder\",\"id\":\"9A8B8BF501A38A36!601\",\"itemType\":32,\"name\":\"released\",\"ownerCid\":\"987654321ABCDEFG\""
;
string
backrefP =
@"""group"":\d+,""iconType"":""\w+"",""id"":""(?<userId>\w+)!\d+"",""itemType"":\d+,""name"":"".+?"",""ownerCid"":""\k<userId>"""
;
string
userId =
""
;
Regex backrefValidRx =
new
Regex(backrefP);
Match foundBackref;
foundBackref = backrefValidRx.Match(backrefValidStr);
if
(foundBackref.Success)
{
// can found the userId
userId = foundBackref.Groups[
"userId"
].Value;
MessageBox.Show(
"can found the userId !"
);
}
foundBackref = backrefValidRx.Match(backrefInvalidStr);
if
(foundBackref.Success)
{
// can NOT found the userId
}
else
{
MessageBox.Show(
"can NOT found the userId !"
);
}
}
4.关于向前匹配(prev match)和向后匹配(post match),以及向前一定不要匹配(prev non-match),和向后一定不要匹配(post non-match)
Python中的语法是:
C#的语法是:
直接给出相关示例代码:
Python中关于前向,后向,匹配,非匹配等的示例代码(记得要import re;):
#------------------------------------------------------------------------------
def
testPrevPostMatch():
# post match: (?=xxx)
# post non-match: (?!xxx)
# prev match: (?<=xxx)
# prev non-match: (?<!xxx)
#note that input string is:
#src=\"http://b101.photo.store.qq.com/psb?/V10ppwxs00XiXU/5dbOIlYaLYVPWOz*1nHYeSFq09Z5rys72RIJszCsWV8!/b/YYUOOzy3HQAAYqsTPjz7HQAA\"
qqPicUrlStr
=
'src=\\"http://b101.photo.store.qq.com/psb?/V10ppwxs00XiXU/5dbOIlYaLYVPWOz*1nHYeSFq09Z5rys72RIJszCsWV8!/b/YYUOOzy3HQAAYqsTPjz7HQAA\\"'
;
qqPicUrlInvalidPrevStr
=
'1234567http://b101.photo.store.qq.com/psb?/V10ppwxs00XiXU/5dbOIlYaLYVPWOz*1nHYeSFq09Z5rys72RIJszCsWV8!/b/YYUOOzy3HQAAYqsTPjz7HQAA\\"'
;
qqPicUrlInvalidPostStr
=
'src=\\"http://b101.photo.store.qq.com/psb?/V10ppwxs00XiXU/5dbOIlYaLYVPWOz*1nHYeSFq09Z5rys72RIJszCsWV8!/b/YYUOOzy3HQAAYqsTPjz7HQAA123'
;
canFindPrevPostP
=
r
'(?<=src=\\")(?P<qqPicUrl>http://.+?\.qq\.com.+?)(?=\\")'
;
qqPicUrl
=
"";
foundPrevPost
=
re.search(canFindPrevPostP, qqPicUrlStr);
print
"foundPrevPost="
,foundPrevPost;
#
if
(foundPrevPost):
qqPicUrl
=
foundPrevPost.group(
"qqPicUrl"
);
print
"qqPicUrl="
,qqPicUrl;
# qqPicUrl=http://b101.photo.store.qq.com/psb?/V10ppwxs00XiXU/5dbOIlYaLYVPWOz*1nHYeSFq09Z5rys72RIJszCsWV8!/b/YYUOOzy3HQAAYqsTPjz7HQAA
print
"can found qqPicUrl here"
;
foundInvalidPrev
=
re.search(canFindPrevPostP, qqPicUrlInvalidPrevStr);
print
"foundInvalidPrev="
,foundInvalidPrev;
# foundInvalidPrev= None
if
(
not
foundInvalidPrev):
print
"can NOT found qqPicUrl here"
;
foundInvalidPost
=
re.search(canFindPrevPostP, qqPicUrlInvalidPostStr);
print
"foundInvalidPost="
,foundInvalidPost;
# foundInvalidPost= None
if
(
not
foundInvalidPost):
print
"can NOT found qqPicUrl here"
;
return
;
C#中关于前向,后向,匹配,非匹配等的示例代码(记得要using System.Text.RegularExpressions;):
void
testPrevPostMatch()
{
//http://msdn.microsoft.com/en-us/library/bs2twtah(v=vs.71).aspx
// post match: (?=xxx)
// post non-match: (?!xxx)
// prev match: (?<=xxx)
// prev non-match: (?<!xxx)
//src=\"http://b101.photo.store.qq.com/psb?/V10ppwxs00XiXU/5dbOIlYaLYVPWOz*1nHYeSFq09Z5rys72RIJszCsWV8!/b/YYUOOzy3HQAAYqsTPjz7HQAA\"
string
qqPicUrlStr =
"src=\\\"http://b101.photo.store.qq.com/psb?/V10ppwxs00XiXU/5dbOIlYaLYVPWOz*1nHYeSFq09Z5rys72RIJszCsWV8!/b/YYUOOzy3HQAAYqsTPjz7HQAA\\\""
;
string
qqPicUrlInvalidPrevStr =
"12345678http://b101.photo.store.qq.com/psb?/V10ppwxs00XiXU/5dbOIlYaLYVPWOz*1nHYeSFq09Z5rys72RIJszCsWV8!/b/YYUOOzy3HQAAYqsTPjz7HQAA\\\""
;
string
qqPicUrlInvalidPostStr =
"src=\\\"http://b101.photo.store.qq.com/psb?/V10ppwxs00XiXU/5dbOIlYaLYVPWOz*1nHYeSFq09Z5rys72RIJszCsWV8!/b/YYUOOzy3HQAAYqsTPjz7HQAA1234"
;
string
canFindPrevPostP =
@"(?<=src=\\"")(?<qqPicUrl>http://.+?\.qq\.com.+?)(?=\\"")"
;
string
qqPicUrl =
""
;
Regex prevPostRx =
new
Regex(canFindPrevPostP);
Match foundPrevPost = prevPostRx.Match(qqPicUrlStr);
if
(foundPrevPost.Success)
{
qqPicUrl = foundPrevPost.Groups[
"qqPicUrl"
].Value;
MessageBox.Show(
"can found the qqPicUrl !"
);
}
Match foundInvalidPrev = prevPostRx.Match(qqPicUrlInvalidPrevStr);
if
(!foundInvalidPrev.Success)
{
MessageBox.Show(
"can NOT found the qqPicUrl !"
);
}
Match foundInvalidPost = prevPostRx.Match(qqPicUrlInvalidPostStr);
if
(!foundInvalidPost.Success)
{
MessageBox.Show(
"can NOT found the qqPicUrl !"
);
}
}
- 【总结】关于(C#和Python中的)正则表达式
- 关于C#中的正则表达式
- 关于C#中的正则表达式isMatch方法
- C# 中的常用正则表达式总结 (转)
- C# 中的常用正则表达式总结
- C# 中的常用正则表达式总结
- C# 中的常用正则表达式总结
- C# 中的常用正则表达式总结
- C# 中的常用正则表达式总结
- C# 中的常用正则表达式总结
- C# 中的常用正则表达式总结
- C# 中的常用正则表达式总结
- C# 中的常用正则表达式总结
- C# 中的常用正则表达式总结
- C# 中的常用正则表达式总结
- C# 中的常用正则表达式总结
- C#中的常用正则表达式总结
- C# 中的常用正则表达式总结
- 使用CSplitterWnd实现拆分窗口
- MySQL数据库的更新语句DELETE与TRUNCATE TABLE
- C++操作SQLite数据库
- js小结
- JEECG移动方案 - 应用系统转换移动应用的中间件实现方案
- 【总结】关于(C#和Python中的)正则表达式
- 用GetHashes软件获取Windows系统Hash密码值
- duplicate symbol for architecture armv7
- 迅捷转换器使用讲解
- IEC61850变电站基本通信结构-原理和模型_7建模规则中的类定义以及MMS映射模型
- 北京邮电大学_2012___考研计算机_复试上机
- linux下C语言编程,include的默认搜索路径
- [精华] 跟我一起写 Makefile
- mahout各个版本下载地址