正则表达式的相关知识

来源:互联网 发布:天刀男性捏脸数据导入 编辑:程序博客网 时间:2024/05/18 03:27
转载至:https://user.qzone.qq.com/2945173161/2?_t_=0.491051455461051
 

此处总结一下,关于正则表达式的相关知识。
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中的语法是:

(?P=name)

Matches whatever text was matched by the earlier group named name.

直接给出示例代码:

Python中关于引用named group的用法示例(记得要import re;):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#------------------------------------------------------------------------------
deftestBackReference():
    # 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(notfoundBackref):
        print"can NOT found userId here";
 
    return

4.关于向前匹配(prev match)和向后匹配(post match),以及向前一定不要匹配(prev non-match),和向后一定不要匹配(post non-match)



?



0 0