正则表达式,刷题时偷懒的后备资源

正则表达式是一种文本模式描述的工具,比如在word文档以及ppt中的文字查找,使用的都是正则表达式。它可以用来检索、替换那些符合某个模式(规则)的文本,在leetcode查找符合要求字符串中十分好用。

基本匹配

  • re.match(pattern, string): 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match() 就返回 None。
  • re.search(attern, string): 扫描整个字符串并返回第一个成功的匹配。
  • re.match() 和 re.search() 都返回一个匹配对象(Match object),如果没有找到匹配则返回 None
  • re.compile(regex, flags=0),regex是正则表达式字符串,flags是可选的标志,用于修改正则表达式的行为
match_obj = re.match(r'\\d+', '123abc456')
if match_obj:
    print(match_obj.group())  # 输出: '123'

高级匹配

  • re.findall(pattern, string): 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表。
  • re.finditer(pattern, string): 扫描整个字符串,找到正则表达式所匹配的所有子串,并返回一个迭代器,该迭代器产生 Match 对象。
print(re.findall(r'\\d+', '123abc456'))  # 输出: ['123', '456']

替换文本

re.sub(): 替换字符串中的一些匹配项。

re.sub(替换的对象,将替换成的内容,文本)

print(re.sub(r'\\d+', 'NUM', '123abc456'))  # 输出: 'NUMabcNUM'

特殊序列

限定符

  • a* a出现0次或多次
  • a+ a出现1次或多次
  • a? a出现0次或1次
  • a{6} a出现6次
  • a{2,6} a出现2-6次
  • a{2,} a出现两次以上

或运算符

  • (a|b) 匹配a或者b
  • (ab)|(cd) 匹配ab或者cd

字符类

  • [abc] 匹配a或者b或者c
  • [a-c] 同上
  • [a-fA-F0-9] 匹配小写+大写英文字符以及数字
  • [^0-9] 匹配非数字字符

元字符

  • \d 匹配数字字符
  • \D 匹配非数字字符
  • \w 匹配单词字符(英文、数字、下划线)
  • \W 匹配非单词字符
  • \s 匹配空白符(包含换行符、Tab)
  • \S 匹配非空自字符
  • . 匹配任意字符(换行符除外)
  • \bword\b \b标注字符的边界(全字匹配)
  • ^ 匹配行首
  • $ 匹配行尾

贪婪/懒惰匹配

<.+> 默认贪婪匹配“任意字符”

<.+?> 懒惰匹配“任意字符”


上示例

说一句,刷题的目标也为了锻炼锻炼思维,直接用正则表达式有点违背这一初衷hhh,但能保证提交结果正确,这里说几个例子,以便各位熟练运用

注:有的题目是需要设计正则表达式,我们再用正则表达式来做这种题显然不合适。


8. 字符串转换整数 (atoi)

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数。

函数 myAtoi(string s) 的算法如下:

  1. 空格:读入字符串并丢弃无用的前导空格(" "
  2. 符号:检查下一个字符(假设还未到字符末尾)为 '-' 还是 '+'。如果两者都不存在,则假定结果为正。
  3. 转换:通过跳过前置零来读取该整数,直到遇到非数字字符或到达字符串的结尾。如果没有读取数字,则结果为0。
  4. 舍入:如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被舍入为 −231 ,大于 231 − 1 的整数应该被舍入为 231 − 1 。

返回整数作为最终结果。

                                                                            (图片来源于leetcode)

这里我们需要读取符号,具体数字,数字前面还不能有0,这里我们可用设置正则化规则进行匹配

import re
class Solution:
    def myAtoi(self, str: str) -> int:
        INT_MAX = 2147483647    
        INT_MIN = -2147483648
        str = str.lstrip()      #清除左边多余的空格
        num_re = re.compile(r'^[\+\-]?\d+')   #设置正则规则
        num = num_re.findall(str)  
        num = int(*num) 
        return max(min(num,INT_MAX),INT_MIN)    

我们这里设置的正则化规则为首先

^ 表示匹配字符串的开头。
[\+\-]? 表示可选的正号或负号。
\d+ 表示一个或多个数字。
findall 方法返回所有匹配的结果,通常是一个列表。先解包列表,再强制类型转换得到最终结果。


65. 有效数字

给定一个字符串 s ,返回 s 是否是一个 有效数字

例如,下面的都是有效数字:"2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789",而接下来的不是:"abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"

一般的,一个 有效数字 可以用以下的规则之一定义:

  1. 一个 整数 后面跟着一个 可选指数
  2. 一个 十进制数 后面跟着一个 可选指数

一个 整数 定义为一个 可选符号 '-' 或 '+' 后面跟着 数字

一个 十进制数 定义为一个 可选符号 '-' 或 '+' 后面跟着下述规则:

  1. 数字 后跟着一个 小数点 .
  2. 数字 后跟着一个 小数点 . 再跟着 数位
  3. 一个 小数点 . 后跟着 数位

指数 定义为指数符号 'e' 或 'E',后面跟着一个 整数

数字 定义为一个或多个数位。

我们这里需要匹配实数以及相对复杂的指数,这里我们就可以分为两种情况,第一种情况分为两小种情况,一是整数二是小数,第二种情况则是指数,我们这里就可以直接来写正则化规则了。

class Solution:
    def isNumber(self, s: str) -> bool:
        pattern = r'^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$'
        res = re.match(pattern,s.strip())
        return bool(res)

一、1. ^[+-]?
        ^:匹配字符串的开头。
        [+-]?:匹配可选的正号 + 或负号 -。? 表示前面的字符或组可以出现 0 次或 1 次。但不是多次
        2. (\d+(\.\d*)?|\.\d+)
        (\d+(\.\d*)?|\.\d+):这是一个分组,匹配整数或小数部分。
        \d+:匹配一个或多个数字。
        (\.\d*)?:匹配可选的小数部分。\. 匹配点号,\d* 匹配 0 个或多个数字。? 表示小数部分可以出现 0 次或 1 次。
        |\.\d+:匹配以点号开头的小数部分。\. 匹配点号,\d+ 匹配一个或多个数字。
        |:表示“或”,匹配前面或后面的表达式。
二、 ([eE][+-]?\d+)?
        ([eE][+-]?\d+)?:这是一个分组,匹配可选的指数部分。
        [eE]:匹配小写大写的 e,表示指数部分的开始。
        [+-]?:匹配可选的正号 + 或负号 -。
        \d+:匹配一个或多个数字。
        ?:表示指数部分可以出现 0 次或 1 次。
三、 $没什么好说的,就是匹配结尾
        


     以上都是些简单情景,如果需要匹配复杂的任务需要设计复杂的匹配规则。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值