正则表达式

正则表达式

(Regular Expression)

一.概念和作用

概念:定义了字符串的模式

__

作用:用来搜索,编辑和处理文本

一句话来说:用来处理跟字符串相关操作,可以用来各个语言中

eg:

1.在 python 中可以用 re 模块来使用正则

2.在 java 中可以用 java.util.regex 包下的类来使用正则

二.正则表达式的使用

1.表示单个字符

字符 功能
. 匹配任意1个字符(除了\n)
\d 匹配数字,即0-9
\D 匹配非数字
\s 匹配空白(空格, tab 键…)
\S 匹配非空白
\w 匹配单词字符(包括 a-z, A-Z, 0-9, _)
\W 匹配非单词字符
[] 匹配[]中列举的字符

注意:\w 匹配的单词字符不仅仅是字母,单词指某语言中的单词,例如中文中的汉字也是可以匹配的或者俄文,希腊字母等都可以

eg:

python

import re 
result = re.match(".", "a") # a
result = re.match("\d", "123") # 1
result = re.match("\D", "a123") # a
result = re.match("\s", " a123") #  (空格)
result = re.match("\S", " a123") # 不匹配,因为第一个字符为空格
result = re.match("\w", "a123") # a
result = re.match("\W", "$a123") # $
result = re.match("[hH]", "Hello World") # H

2.表示数量(匹配多个字符)

字符 功能
* 匹配前一个字符出现0次或者无限次
+ 匹配前一个字符出现1次或者无限次
? 匹配前一个字符出现0次或者1次
{m} 匹配前一个字符出现 m 次
{m,} 匹配前一个字符至少出现 m 次
{m,n} 匹配前一个字符出现从 m 到 n 次

eg:

python

import re
re.match(".*","abc") # abc 表示任意字符,任意数量,结果匹配
re.match("\w+", "abc") # abc 表示单词字符至少出现一次
re.match("\w?", "1abc") # 结果匹配 表示单词字符可以出现0次或者1次
re.match("\d{5}","11111222abc") # 11111 表示出现5次数字
re.match("\d{5,}","11111222abc") #11111222 表示数字至少要出现5次
re.match("\d{5,7}","11111222abc") #1111122 表示匹配5-7个数字

3.表示边界

字符 功能
^ 匹配字符串的开头
$ 匹配字符串的结尾
\b 匹配一个单词的边界
\B 匹配非单词边界

eg:

python

import re
re.match("^\d","123abc") #1 表示以数字开头
re.match("\d+\w+\d$","123abc5") # 匹配
re.match(r"\w+\s\bve", "he ve llo world") # ho ve 表示至少一个单词字符然后空格ve,至于涉及到的 r 后面会讲解(注意:\b 只匹配边界不匹配任何字符,比如空格之类的都不匹配)
re.match("\w+ve", "hover")#hove

4.匹配分组

字符 功能
\ 匹配左右任意一个表达式,即或的意思
(ab) 将括号中字符作为一个分组
\num 引用分组 num 匹配到的字符串(从1开始)
(?P\) 分组起别名
(?P=name) 引用别名为 name 的分组匹配到的字符串

eg:

python

import re
re.match("\w|\s","a1") # a 表示字符或者空白
re.match("\w(\d)aaa", "a1aaa").group(1) # 1
re.match(r"\w(\d)aaa\1","a1aaa1") # a1aaa1
re.match("\w(?P<name>\d)aaa(?P=name)","a1aaa1")#a1aaa1

5.贪婪与非贪婪

贪婪:表示数量词的字符总是尝试匹配尽可能多的字符

非贪婪:表示数量词的字符总是尝试匹配尽可能少的字符,在数量词后面加上?关闭贪婪模式

python 中默认的贪婪

import re
s = "This is a number 234-235-22-423"
result = re.match(".+(\d+-\d+-\d+-\d+)", s)
r.group(1) # '4-235-22-423' 解释: .+会尽可能多的匹配字符,只要让\d+能满足即可,所以.+从 This 一直匹配到了23只留给\d+一个4(这就是贪婪模式)
result = re.match(".+?(\d+-\d+-\d+-\d+)", s)
r.group(1) # '234-235-22-423' 解释: 当在.+后面加上?之后即关闭了贪婪模式成为了非贪婪所以.+会尽可能少的去匹配支付,从 This 一直匹配到了 number 因此后面的\d+就匹配了234

三. python 中正则表达式的一些使用

0.python 中使用的是 re 模块

1.match方法

前面的例子中都是使用的 match()所以这里简单说下

match 方法是从头开始匹配的

result = re.match("正则表达式", "要进行匹配的字符串")

注意match 方法的返回值

匹配返回匹配的字符串

不匹配返回的是 None

result.group()

group方法:

在不传参数的情况下默认参数是0即返回所有的匹配结果

当指定1,2或者n的时候,返回的是通过()分组第 n 组匹配的结果

2.原始字符串

在 match 方法的第一个参数前加上 r 表示原始字符串

re.match(r"\d","1") # 1

通过一个例子来看为什么要有原始字符串

s = "\nabc"
print(s) # 结果是回车 abc
s = "\\nabc" 
print(s) # 结果是 \\nabc (在前面加上\表示转义)
#问题来了,这时候我们需要"\\nabc"的匹配规则呢
re.match("\\nabc", "\\nabc")#结果并不匹配
re.match("\\\\nabc","\\nabc")#结果匹配
# 因为匹配规则中的\也会被理解为转义字符,所以导致要匹配对应的字符串就要在规则中出现2倍数量的在字符串中的\才可以正常匹配

通过上面的例子我们知道要匹配转义字符的时候,在规则中要有字符串中\的2倍的数量,这未免太麻烦了

因此在 python 中为了解决这个问题增加了原始字符串即在 match(r””,””)中加上 r 表示原始字符串

re.match(r"\\nabc","\\nabc")#结果匹配

所以一般情况下,都会在匹配规则前增加 r 形成习惯

3.search方法

re.search(r"\d+","lalalal9999lalal888")#999

search方法会去字符串中搜过第一个能匹配规则的串并返回

4.findall 方法

re.findall(r"\d+", lalal9999lalal888) # [9999, 888] 

findall 方法会在字符串中搜索所有蛮族规则的字符串并以列表的形式返回

5.sub 方法

re.sub(r"\d+","100","python = 999") # python = 100

sub 方法是将匹配到的字符串进行替换为第二个参数

sub 方法第二个参数可以接受一个函数来对数据进行处理

def add(temp):
    strNum = temp.group()
    num = int(strNum)+1
    return str(num)
re.sub(r"\d+",add,"python = 99") # python = 100

6.split 方法

re.split(r":|,m","info:cml,33|dd mm") #[info,cml,33,dd,mm]

split方法会按照规则中的多个或者一个字符来对字符串进行切割并以列表的形式返回

四. java 中正则表达式的一些使用

注意

在 java 中表示规则的字符要用到两个,比如说python 中的\d
在 java 中是\d

java 中对于正则表达式主要用到java.util.regex 包下三个类

Pattern

matches 方法

matches("regex","str")//判断str 是否匹配规则,返回值为 boolean 值
Pattern.matches("\\d","1") // true

compile方法 (举例参照下面的 Matcher 类中):对正则的规则进行记录

Matcher

通过一个例子来说明:

String str = "This number A1234 . Ok ?";
String regex = "(\\D*)(\\d+)(.*)";
Matcher matcher = Pattern.compile(regex).matcher(str);
if(matcher.find()){
    System.out.println(matcher.group(0))//This number A1234 . Ok ?    
    System.out.println(matcher.group(1))//This number A
    System.out.println(matcher.group(2))//1234
    System.out.println(matcher.group(3))// . Ok ?
}

同样的 Matcher 中也有更多功能的方法


start()

end()

find()

replace()

PatternSyntaxException

主要是用来表示一个正则表达式中的语法错误的(不详述了)

java 的例子参考资料:Java 正则表达式