Regular Expression语法

Regular Expression功能

  • 正则表达式描述了一种字符串匹配模式(pattern),
  • 通过该模式可以用来:
  1. 检查一个串是否含有某种子串;
  2. 将匹配的子串替换;
  3. 从某个串中取出符合某个条件的子串等。

Regular Expression基本构成

  • 正则表达式是由普通字符(例如字符 a到z)以及特殊字符(称为"元字符")组成的文字模式;
  • 正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合;
  • 使用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。

普通字符

  • 普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。
  • 普通字符包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。

特殊字符

  • 特殊字符,就是一些有特殊含义的字符,
  • 元字符要求在试图匹配它们时特别对待,若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面。如下表所示,列出了正则表达式中的特殊字符:
    在这里插入图片描述
特殊字符之限定符
  • 限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。
  • 有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种,如下表所示:
    在这里插入图片描述
  • 限定符出现在范围表达式之后,它应用于整个范围表达式
  • *+限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ?就可以实现非贪婪或最小匹配。
示例
  1. 用正则表达式匹配一个正整数,[1-9]设置第一个数字不是 0,[0-9]* 表示任意多个数字,也可以是0个。
    /[1-9][0-9]*/

  2. 用正则表达式至少指定一位但至多两位数字,即数字范围是0~99
    /[0-9][0-9]*/

  3. 用正则表达式匹配最多两位数的正整数,即数字范围是1~99
    /[1-9][0-9]?*/ 或者 /[1-9][0-9]{0,1}*/

  4. 用正则表达式搜索 HTML 文档,查找在 h1 标签内的内容

  • 比如h1标签的内容是<h1>S5850-24T16S</h1>
  • 贪婪匹配:会匹配从开始小于符号 (<) 到关闭 h1 标记的大于符号 (>) 之间的所有内容。
    /<.*>/
  • 非贪婪匹配(最小匹配):会匹配第一个小于符号 (<) 和第一个大于符号 (>) 之间的所有内容,也就是匹配第一个h1
    /<.*?>/ 或者 /<\w+?>/
特殊字符之定位符
  • 定位符能够将正则表达式固定到行首或行尾;
  • 定界符也能够将正则表达式固定在单词开头、单词内、单词结尾。
    在这里插入图片描述
  • 不能将限定符与定位符一起使用
  • 若要匹配一行文本开始处的文本,请在正则表达式的开始使用^字符。不要将 ^的这种用法与中括号表达式内的用法混淆。
示例
  1. 用正则表达式匹配一个章节标题,该标题只包含两个尾随数字,标题处在行首和行尾之间:
    /^Chapter [1-9][0-9]{0,1}$/ 或者 /^Chapter [1-9][0-9]?$/

  2. 用正则表达式匹配单词 Second的开头三个字符:
    /\b Sec/

  3. 用正则表达式匹配单词 Second的结尾三个字符:
    /\b ond/

  4. 用正则表达式匹配单词 Second的中间三个字符con,但是不会匹配console中的字符串con:
    /\B con/

选择
  • 将圆括号()所有选择项括起来,相邻的选择项之间用 | 分隔,表示匹配条件有多个,彼此之间的关系是或
  • 用圆括号()进行会使相关的匹配会被缓存,可以用?:放在第一个选项前来取消匹配缓存。
  • 正向预查?=,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串;
  • 负向预查?!,在任何开始不匹配圆括号内正则表达式模式的位置来匹配搜索字符串。
反向引用
  • 使用圆括号()进行数据匹配,会将匹配成功的数据存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。
  • 缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。
  • 每个缓冲区都可以使用 \n 访问,其中 n 为一个标识特定缓冲区的数字编号。(比如\11表示访问第十一个子匹配的缓冲区)
示例
  1. 使用正则表达式查找文本中两个相同的相邻单词
  • 输入字符串:“good good study, day day up”

  • 正则表达式:/\b([a-z]+) \1\b/ig

  • 匹配结果:good goodday day

  • 该正则表达式的匹配条件可以看做三个部分:([a-z]+) (一个空格)和 \1
    (1)[a-z]+ 表示匹配一个或者多个字母,([a-z]+)表示子匹配项,匹配结果会存储在编号为1的缓冲区
    (2) (一个空格)表示匹配一个空格
    (2) \1 表示匹配编号为1的缓冲区数据

  • \b 表示匹配单词的边界,比如“is issued”字符串就不会别匹配

  • \i 表示匹配时不区分大小写

  • \g 表示将该匹配表达式应用到输入字符串中,能够查找到的尽可能多的匹配。(多次匹配)

<think>好的,我现在需要解决用户提出的关于正则表达式中“无效范围”错误的问题。用户遇到了“invalid range in regular expression”这个报错,想知道错误原因和修复方法。首先,我得回忆一下正则表达式中的字符类(character classes)的语法规则,尤其是范围(range)的使用。 根据引用[2]提到的,POSIX正则表达式有BRE和ERE两种语法,但不管哪种,字符类中的范围都需要正确书写。比如,用户可能在正则表达式中使用了类似[a-Z]这样的无效范围,因为a的ASCII码是97,Z是90,显然Z在a前面,所以范围是无效的。这时候正确的应该是[a-zA-Z]或者调整顺序,比如[A-Za-z]。 另外,用户可能在某些特殊字符的位置使用了连字符,而没有正确转义。例如,在字符类中,如果连字符不在开头或结尾,并且不是用来表示范围的话,可能需要转义或者放在不会形成范围的位置。比如,要匹配连字符本身,应该写成[-a-z]或者[a-z-],或者转义成[\-a-z],不过根据正则表达式规则,在字符类中连字符如果不在中间作为范围符号的话,可以不需要转义,直接放在开头或结尾即可。 再考虑用户是否在字符类中错误地组合了字符,比如把多个范围连在一起而没有正确分隔。比如,[a-zA-Z0-9_]是正确的,但如果写成[a-z-A-Z]可能中间的两个连字符会被误认为范围分隔符,导致错误。这时候应该检查是否有连续的连字符或者范围顺序颠倒的情况。 还有一种情况是用户可能在字符类中使用了无效的字符,比如未转义的特殊字符,如^、]、\等。比如,如果用户想在字符类中包含]而没有转义,会导致语法错误,但这里的问题是关于范围的错误,所以更可能的是范围定义的问题。 另外,引用[4]提到\s匹配空白字符,可能用户在使用类似[\s-]这样的结构时,如果连字符的位置不对,也会导致范围错误。例如,写成[a-\s]的话,因为\s代表的是空白字符,而a的ASCII码比\s中的字符(比如空格是32)大,导致范围无效。正确的写法应该是把连字符放在正确的位置,比如[-\s]或者[\s-]。 总结可能的错误原因: 1. 字符范围顺序颠倒,如[z-a]。 2. 连字符位置不正确,导致形成无效范围。 3. 在字符类中错误地包含了特殊字符而没有转义,导致解析错误。 修复方法可能包括: - 检查所有字符范围,确保起始字符的ASCII码小于结束字符。 - 将连字符放在字符类的开头或结尾,或者转义它(如果需要作为普通字符)。 - 确保特殊字符如^、]等被正确转义。 比如,用户的正则表达式如果是这样:[a-Z],应该改为[A-Za-z];如果是[z-a],则改为[a-z];如果是[a-z-],则正确匹配小写字母和连字符;如果是[a-9],因为a的ASCII码97大于9的ASCII码57,所以无效,应改为[0-9a-z]等。 需要提醒用户检查正则表达式中所有字符类的范围定义,确保每个范围都是有效的,并且连字符的正确使用。</think>### 正则表达式中“invalid range”错误的解决方案 #### 错误原因 正则表达式中出现`invalid range in regular expression`错误的主要原因是**字符类(Character Class)中定义了无效的范围**,具体表现为: 1. **范围顺序颠倒**:例如`[z-a]`,字符`z`的ASCII码(122)大于`a`(97),无法形成有效范围[^2]; 2. **连字符(`-`)未正确转义或位置错误**:在字符类中,连字符若不在开头或结尾,且未用于定义范围时,会被视为普通字符。例如`[a-9]`会尝试定义从`a`(97)到`9`(57)的无效范围; 3. **包含特殊字符未转义**:例如`[a-Z]`中`Z`的ASCII码(90)小于`a`(97),导致范围无效; 4. **字符类中包含非ASCII字符**:如`[a-好]`,中文字符与英文字符的编码差异导致范围无效。 --- #### 修复方法 1. **调整范围顺序** 确保起始字符的ASCII码小于结束字符。例如: - ❌ `/[z-a]/` → ✅ `/[a-z]/` - ❌ `/[9-0]/` → ✅ `/[0-9]/` 2. **正确使用连字符** - 若需匹配连字符本身,将其放在字符类**开头或结尾**: - ❌ `/[a-z-@]/` → ✅ `/[-a-z@]/` 或 `/[a-z@-]/` - 若需定义范围,确保中间无其他干扰字符: - ❌ `/[a-zA-Z0-9_!-]/` → ✅ `/[a-zA-Z0-9_!-]/`(`!`的ASCII码为33,`-`为45,此处范围`!-`实际表示从`!`到`-`的字符) 3. **转义特殊字符** 对于包含`]`、`^`等特殊字符的情况,需转义或调整位置: - ❌ `/[a-z]]/` → ✅ `/[a-z\]]/` 或 `/[]a-z]/` 4. **避免混合ASCII与非ASCII字符** 如`/[a-好]/`应拆分为明确的范围或单独列出字符。 --- #### 示例代码 ```python import re # 错误示例:无效范围 [z-a] try: re.compile(r'[z-a]') except re.error as e: print(e) # 输出:invalid range in character set at position 2 # 修复后:有效范围 [a-z] pattern = re.compile(r'[a-z]') print(pattern.findall("Hello123")) # 输出:['e', 'l', 'l', 'o'] ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值