随便学学Python-day16-正则表达式

本文围绕Python中的正则表达式展开,介绍了正则表达式是让字符串处理变简单的工具,阐述了匹配符号、检测类符号、匹配次数、分组和分支等规则,还讲解了Python内置的re模块,包括fullmatch、match、search等函数的使用方法。

day16-正则表达式

正则表达式匹配符号

re模块是python内置的专门提供处理正则表达式函数的模块

1.什么是正则表达式

正则表达式是一种可以让字符串处理变得很简单的工具

正则表达式就是通过各种正则符号来描述字符串的规则

在不同的编程语言中,正则的语法是相同的,但是表示方式不同:python - ‘正则表达式’,js - /正则表达式/

2.正则符号

1)普通字符 - 普通字符在正则表达式中表示这个符号本身

fullmatch(正则表达式,字符串) - 判断字符串是否符合正则所描述的规则,如果符合结果不是None,否则是None

2). - 匹配一个任意字符

‘a.b’ - 匹配一个长度是3的字符串,第一个字符是a,最后一个字符是b,中间一个是任意字符

re_str = 'a.b'
result = fullmatch(re_str, 'akb')
print(result)    # <re.Match object; span=(0, 3), match='akb'>

result = fullmatch(re_str, 'a+b')
print(result)    # <re.Match object; span=(0, 3), match='a+b'>

3)\d - 匹配一个任意数字

re_str = 'a\db'    # 匹配一个长度是3,第一个字符是a,最后一个字符是b,中间是一个任意数字字符
result = fullmatch(re_str, 'a9b')
print(result)    # <re.Match object; span=(0, 3), match='a9b'>

result = fullmatch(re_str, 'a0b')
print(result)   # <re.Match object; span=(0, 3), match='a0b'>

4)\s - 匹配一个空白字符

空白字符:空格字符、\n、\t

re_str = 'abc\s123'
result = fullmatch(re_str, 'abc 123')
print(result)    # <re.Match object; span=(0, 7), match='abc 123'>

result = fullmatch(re_str, 'abc\t123')
print(result)    # result = fullmatch(re_str, 'abc 123')

result = fullmatch(re_str, 'abc\n123')
print(result)   # <re.Match object; span=(0, 7), match='abc\n123'>

result = fullmatch(re_str, 'abc123')
print(result)   # None

5)\w(了解) - 匹配一个字母、数字或者下划线(ASCII码表以外的字符都可以匹配)

re_str = '\d\w\d'
result = fullmatch(re_str, '2看8')
print(result)

6)\D - 匹配任意一个非数字字符

\S - 匹配任意一个非空白字符

re_str = 'a\Db'
result = fullmatch(re_str, 'a9b')
print(result)     # None

result = fullmatch(re_str, 'a就b')
print(result)    # <re.Match object; span=(0, 3), match='a就b'>

re_str = '\d\S\d'
result = fullmatch(re_str, '2=8')
print(result)    # <re.Match object; span=(0, 3), match='2=8'>

result = fullmatch(re_str, '2 8')
print(result)    # None

7)[字符集] - 匹配字符集中出现的任意一个字符

"""
注意:a.一个[]只能匹配一个字符
     b.在[]中可以将-放在两个字符之间表示范围,但是-前面的字符的编码值必须小于后面的字符的编码值
     c. 在[]中-只有在两个字符之间才有特殊意义,如果在最前面或者最后面就表示-本身

[a1+]  - 匹配字符a或者字符1或者字符+
[\dxy] 、 [x\dy] 、 [xy\d] - 匹配一个任意数字或者x或者y

[1-9]  - 匹配1到9的任意一个数字字符
[a-z]  - 匹配任意一个小写字母
[A-Z]  - 匹配任意一个大写字母
[a-zA-Z]
[\u4e00-\u9fa5]   -  匹配任意一个中文字符

下列写法都支持:
[a-z+=/]
[1a-z2]
[2-8a-z]
[\da-z]
"""
re_str = 'a[xy0]b'    # 匹配一个长度是3,第一个字符是a,最后一个是b,中间是x、y、0 中的任意一个字符的字符串
result = fullmatch(re_str, 'a0b')
print(result)

re_str = 'a[\dmn]b'
result = fullmatch(re_str, 'amb')
print(result)

re_str = 'a[1-9]b'
result = fullmatch(re_str, 'a9b')
print(result)

8)[ ^字符集 ] - 匹配不在字符集中的任意一个字符

"""
[^abc]   -  匹配除了a、b、c以外的任意字符
[^\d]   -   匹配任意一个非数字字符
[^a-z]  -  匹配任意一个非小写字母的字符
"""
re_str = '\d[^abc]\d'
print(fullmatch(re_str, '3好6'))

re_str = '\d[abc^]\d'
print(fullmatch(re_str, '3^6'))

检测类符号

匹配类的符号,一个符号需要对应一个字符;检测类的符号不影响字符串的长度,只是在匹配成功后检测符号所在的位置是否符合要求

1.\b和\B

\b - 检测是否是单词边界

\B - 检测是否不是单词边界

单词边界 - 生活中可以将两个单词区分开来的字符,例如:空白、标点符号、字符串开头和字符串结束

re_str = r'abc,\b123'
result = fullmatch(re_str, 'abc,123')
print(result)

re_str = r'\b\d\d\s\babc'   # '\b\d\d\s\babc'
result = fullmatch(re_str, '89 abc')
print(result)

re_str = r'\d\d\B'
str1 = '啥时间89sksj28jsk 09 会计89, jss,85,结束素数10'
result = findall(re_str, str1)
print(result)

2. ^ - 检测字符串开头

re_str = '^\d\d\d'
result = fullmatch(re_str, '892')
print(result)

re_str = '^\d\d\d'
result = findall(re_str, '8890shsh892快捷键920js110ss334')
print(result)   # ['889']

3. $ - 检测是否是字符串结尾

re_str = '\d\d\d$'
result = findall(re_str, '8890shsh892快捷键920js110ss334')
print(result)    # ['334']

匹配次数

1. + - 一次或多次(至少一次)

"""
a+  - 字符a出现一次或者多次
\d+  -  匹配一次或者多次任意数字字符
.+  -  匹配一次或者多次任意字符
[xyz]+  
"""
re_str = 'xa+y'
result = fullmatch(re_str, 'xay')
print(result)   # <re.Match object; span=(0, 3), match='xay'>

result = fullmatch(re_str, 'xaay')
print(result)   # <re.Match object; span=(0, 4), match='xaay'>

result = fullmatch(re_str, 'xaaaaaaaay')
print(result)   # <re.Match object; span=(0, 10), match='xaaaaaaaay'>

re_str = 'x\d+y'      # x\d\d\d\d\dy
print(fullmatch(re_str, 'x2y'))
print(fullmatch(re_str, 'x2823y'))

re_str = '1[xyz]+1'     #  1[xyz][xyz][xyz][xyz]1
print(fullmatch(re_str, '1x1'))
print(fullmatch(re_str, '1xx1'))
print(fullmatch(re_str, '1xy1'))

2. * - 匹配0次或多次(任意次数)

re_str = 'xa*y'
print(fullmatch(re_str, 'xy'))

3. ? - 匹配0次或1次

print(fullmatch('0?abc', '0abc'))

# 练习:写一个正则表达式来检测字符串是否是合法的整数
# 89, 123, -90, +56  - 合法
# 09, -002,+030 ,++89 - 不合法
re_str = '[-+]?[1-9]\d*'

4. {}

# {N}  - 匹配N次
# {M,N} - 匹配M到N次(至少M次,最多N次)
# {M,}  - 匹配至少M次
# {,N}  - 匹配最多N次
print(fullmatch('a{4}\d{3}', 'aaaa345'))
print(fullmatch('a{2,4}\d{2,}[a-z]{,3}', 'aaaa887hjk'))

5.贪婪和非贪婪

在匹配次数不确定的时候,匹配分为贪婪和非贪婪两种,默认都是贪婪的

1)贪婪 - 匹配次数不确定默认就是贪婪(+、*、?、{M,N}、{M,}、{,N})

贪婪:在能匹配成功的前提下,取匹配次数最多的结果。(假设3次、4次、6次都能匹配成功,最后取6次)

2)非贪婪 - 在匹配次数不确定的次数后加?(+?、*?、??、{M,N}?、{M,}?、{,N}?)

非贪婪:在能匹配成功的前提下,取匹配次数最少的结果。(假设3次、4次、6次都能匹配成功, 最后取3次)

re_str = r'a.+b'
# amnmb
print(findall(re_str, 'amnmb123lk计算机上'))

分组和分支

1.() - 分组

分组就是将正则表达式中的某部分用()括起来看成一个整体,然后进行整体的操作。

在正则表达式中一个()表示一个分组

1)整体操作

‘(\d{2}[a-z]{3})+’

2)整体重复

\M - 重复前面第M个分组匹配到的内容

re_str = r'(\d{3})ab\1'
print(fullmatch(re_str, '789ab789'))
print(fullmatch(re_str, '112ab112'))

re_str = r'(\d{3})([a-z]{2})=\1{2}'
print(fullmatch(re_str, '341ab=341341'))

re_str = r'(\d{3})([a-z]{2})=\2\1'
print(fullmatch(re_str, '341ab=ab341'))

2. | - 分支

正则1 | 正则2

# 练习:写一个正则表达式,能够匹配一个字符串是:abc后面是三个任意数字,或者三个任意大写字母
# 'abc827'、'abcKNM'
re_str = 'abc\d{3}|abc[A-Z]{3}'
print(fullmatch(re_str, 'abcMKS'))

re_str = 'abc(\d{3}|[A-Z]{3})'
print(fullmatch(re_str, 'abc987'))

3.转义符号

在正则中有特殊意义的符号前加 \ 让这个符号的功能消失,表示这个这个符号本身

re_str = '\d{2}\.[a-z]{3}'
print(fullmatch(re_str, '89.hsk'))
print(fullmatch(re_str, '89Mhsk'))   # None

re_str = '\d\+'
print(fullmatch(re_str, '8+'))

# 注意:除了在[]中有特殊意义的符号外(-和^),其他的符号在[]里面都表示这个符号本身
re_str = '\d[+*|?$^()-]\d'
print(fullmatch(re_str, '2)8'))

re模块

1.fullmatch

fullmatch(正则表达式,字符串) - 判断字符串和正则表达式是完全匹配, 如果可以匹配返回匹配对象,否则返回None

2.match

match(正则表达式,字符串) - 判断字符串的开头是否和正则匹配,如果可以匹配返回匹配对象,否则返回None

3.search

search(正则表达式,字符串) - 获取字符串中第一个满足正则表达式的子串,如果可以匹配返回匹配对象,否则返回None

4.finally

finally(正则表达式,字符串) - 获取字符串中所有满足正则表达式的子串,返回一个列表

5.split

split(正则表达式,字符串) - 将字符串中所有满足正则表达式的子串作为切割点,对字符串进行切割

6.sub

sub(正则表达式,字符串1,字符串2) - 将字符串2中满足正则表达式的子串都替换成字符串1

<think>首先,用户的问题是关于正则表达式去除重复字符串的方法。用户说:“我想使用正则表达式去除重复的字符串 请问正则表达式 去除重复字符串 方法”。所以,核心是提供正则表达式的方法来去除字符串中的重复字符。 根据系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式使用$$...$$并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识。 用户提供了几个引用: - 引用[1]:关于Java中使用正则表达式去除重复字符和点号。 - 引用[2]:Java代码示例,使用正则表达式去除重复字符。 - 引用[3]:JavaScript示例,使用正则表达式去除重复字符。 这些引用展示了如何使用正则表达式在字符串中去除重复字符。关键点是使用反向引用和替换。 回顾引用: - 在引用[1]中,正则表达式是"(.)\\1+",替换为"$1",意思是匹配任何字符(.)后跟一个或多个相同字符(\\1+),然后替换为单个字符($1)。 - 在引用[2]中,同样使用"(.)\\1+"替换为"$1"。 - 在引用[3]中,使用JavaScript的/(.)\1+/g,替换为'$1'。 所以,通用的正则表达式方法是:匹配重复字符的模式,然后用反向引用来替换。 对于用户的问题,我需要提供一个清晰的解释和方法。 回答结构: 1. **解释正则表达式方法**:使用中文解释如何去除重复字符。 2. **提供示例**:给出代码示例,可能用Java或JavaScript,因为引用中有这些。 3. **生成相关问题**:在结尾添加相关问题。 系统指令说“生成相关问题”,并在示例中显示“§§相关问题§§”,所以我需要在回答后添加相关问题。 另外,指令说“回答中引用的段落末尾自然地添加引用标识”。所以,如果我引用或基于引用内容,我需要添加[^n]。 用户的问题是通用的“正则表达式去除重复字符串”,所以我应该给出通用的方法,然后参考引用中的具体实现。 步骤: 1. **介绍方法**:正则表达式使用捕获组和反向引用来匹配重复字符。 - 模式:`(.)\1+`,其中`(.)`捕获单个字符,`\1+`匹配一个或多个相同字符。 - 替换:`$1`,保留第一个字符。 - 这适用于任何支持正则表达式的语言。 2. **代码示例**:既然引用中有Java和JavaScript,我可以提供两种语言的示例。 - 例如,在Java中:`string.replaceAll("(.)\\1+", "$1")` - 在JavaScript中:`str.replace(/(.)\1+/g, '$1')` 3. **解释**:为什么这样工作?正则表达式匹配连续重复的字符序列,并替换为单个字符。 4. **添加引用**:在解释中,自然地提到引用来源。例如,“如引用[1]所示,... [^1]”。 5. **相关问题**:生成3-4个相关问题,如: - 如何处理不连续的重复字符? - 如何去除特定字符的重复? - 正则表达式在去除重复字符时的性能如何? 确保回答清晰、结构良好。 最终回答结构: - 开头:直接回答问题。 - 主体:解释方法,提供示例。 - 结尾:相关问题。</think>### 正则表达式去除重复字符串的方法 要使用正则表达式去除字符串中的重复字符,核心方法是利用**捕获组**和**反向引用**来匹配连续重复的字符序列,并通过替换操作保留单个字符。以下是详细步骤和示例: #### 正则表达式方法 - **核心模式**:`(.)\1+` - `(.)`:捕获组,匹配任意单个字符(包括汉字、字母等),并将其存储在第一个捕获组中。 - `\1+`:反向引用,匹配一个或多个与第一个捕获组相同的字符。 - **替换操作**:使用`$1`替换匹配到的重复序列,其中`$1`代表第一个捕获组的内容(即单个字符)。 - **全局匹配**:添加`g`标志(在支持正则的语言中),确保处理整个字符串的所有重复序列。 - 这个方法适用于连续重复字符(如"我我"变为"我"),但不会处理非连续重复(如"我你你"中的"你")。如引用[1]所示,该方法在Java中可高效去除重复汉字[^1]。 #### 代码示例 以下是不同语言中的实现示例: 1. **Java 示例**(基于引用[2]): ```java String content = "Java不不不不好好学学,其实也也也也还好好"; content = content.replaceAll("(.)\\1+", "$1"); // 使用双反斜杠转义 System.out.println(content); // 输出: "Java不好学,其实也好" ``` 解释:`replaceAll`方法应用正则表达式`(.)\\1+`匹配重复字符(如"不不"),并用`$1`替换为单个字符(如"不")。该方法简洁高效[^2]。 2. **JavaScript 示例**(基于引用[3]): ```javascript let str = "aaaccbb bb cc dddd"; let newStr = str.replace(/(.)\1+/g, '$1'); // 使用单反斜杠和g标志 console.log(newStr); // 输出: "acb b c d" ``` 解释:`replace`方法结合`g`标志全局匹配重复序列(如"aaa"变为"a")。正则表达式`/(.)\1+/g`直接匹配连续重复项[^3]。 3. **通用正则表达式**: - 模式:`(.)\1+` - 替换:`$1` - 支持语言:Python(`re.sub`)、C#(`Regex.Replace`)等,语法类似。 #### 注意事项 - **处理非连续重复**:此方法仅针对连续重复字符。如果需处理非连续重复(如"a b a"),需结合其他方法(如遍历或哈希表)。 - **特殊字符处理**:如果字符串包含正则元字符(如`.`或`*`),需转义处理。 - **性能**:正则表达式在短文本中高效,但对于长字符串可能影响性能,建议测试边界情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值