无需登录 数据私有 本地保存

正则表达式速查表 - 语法规则及示例

106
0
0
0

常见问题

Q:什么是正则表达式?它主要有哪些用途?
A:正则表达式(Regular Expression,简称 Regex)是一种用于描述字符串匹配模式的工具语言。它由普通字符和特殊元字符组成,能够高效地完成文本搜索、替换、验证和提取等任务。在实际开发中,正则表达式的典型用途包括:表单输入验证(如邮箱、手机号格式校验)、日志文件分析与过滤、数据清洗与格式转换、字符串批量替换、网络爬虫中的URL匹配和内容提取等。几乎所有主流编程语言都内置了正则表达式支持,它是开发者必备的核心技能之一。
Q:正则表达式中的特殊字符如何正确转义?
A:正则表达式中的特殊字符(也称元字符)包括 .*+?()[]{}^$|\ 等。当需要匹配这些字符的字面值时,必须在它们前面加上反斜杠 \ 进行转义。例如,匹配实际的点号应写作 \. 而非 .;匹配左括号应写作 \(。另外,在JavaScript中使用字符串字面量时,反斜杠本身也需要转义,因此需要写成双反斜杠 \\.。建议在编写正则时使用原始字符串(如Python的 r'...' 语法)来减少转义层级。
Q:贪婪匹配和非贪婪匹配有什么区别?什么时候使用哪种?
A:贪婪匹配(Greedy)和非贪婪匹配(Lazy)是量词的两种行为模式。贪婪模式是默认行为,量词会尽可能多地匹配字符,直到后续模式无法匹配时才回溯。非贪婪模式通过在量词后加 ? 启用,会尽可能少地匹配字符。例如,对于字符串「<div>Hello</div>」,正则 <.+>(贪婪)会匹配整个「<div>Hello</div>」,而 <.+?>(非贪婪)只会匹配「<div>」。一般建议:当匹配HTML标签内容或特定边界之间的文本时使用非贪婪模式;当需要匹配包含特定模式的最长字符串时使用贪婪模式。
Q:什么是捕获组?如何使用反向引用?
A:捕获组是用圆括号 () 包围的正则子表达式,它会将括号内匹配到的文本保存下来供后续使用。捕获组按从左到右的顺序自动编号:第一个 () 是第1组,第二个是第2组,以此类推。反向引用允许在正则模式中引用之前捕获的内容,语法为 \1\2 等。例如,正则 (\w+)\s+\1 可以匹配连续重复出现的单词,如「the the」。命名捕获组(如 (?<name>pattern))则通过名称而非编号来引用,可读性更好。在替换操作中,可以使用 $1$2$<name> 来引用捕获的内容。
Q:零宽断言(Lookaround)是什么?有哪些实际应用场景?
A:零宽断言(也称「环视」或 Lookaround)是匹配「位置」而非「内容」的特殊语法。它断言某个位置的上下文满足特定条件,但不消耗任何字符。零宽断言有四种:正向先行断言 (?=pattern) 匹配后面跟着 pattern 的位置;负向先行断言 (?!pattern) 匹配后面不跟 pattern 的位置;正向后行断言 (?<=pattern) 匹配前面有 pattern 的位置;负向后行断言 (?<!pattern) 匹配前面没有 pattern 的位置。实际应用包括:提取被引号包围但不包含引号本身的内容(使用后行和先行断言)、匹配不以特定前缀开头的字符串(负向后行断言)、在不改变捕获组编号的前提下添加匹配条件等。
Q:正则表达式中常用的标志位(Flags)有哪些?
A:标志位用于调整正则表达式的匹配行为。最常用的标志位包括:g(全局模式)使匹配返回所有结果而非仅第一个;i(忽略大小写)使匹配不区分字母大小写;m(多行模式)使 ^$ 匹配每行的行首和行尾而非整个字符串的首尾;s(点号匹配换行)使 . 也能匹配换行符 \nu(Unicode模式)正确处理四字节UTF-16字符和Unicode属性;y(粘连模式,JavaScript特有)强制从 lastIndex 位置开始匹配。标志位可以组合使用,如 /pattern/gi 同时启用全局匹配和忽略大小写。在Python中,使用 re.IGNORECASEre.MULTILINE 等常量来设置标志位。
Q:如何用正则表达式匹配常见的邮箱地址和URL?
A:匹配邮箱的常用正则模式为 [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,},它匹配「用户名@域名.顶级域名」的标准格式。需要注意的是,完整的邮箱验证应遵循RFC 5322规范,但该规范极其复杂,实际项目中通常使用上述简化版本。匹配URL的常用模式为 https?://[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&:/~+#])?,它支持HTTP和HTTPS协议,匹配常见的域名和路径格式。在实际使用中,建议根据具体需求适当简化或调整这些模式,避免过度复杂的正则导致性能问题或维护困难。
Q:在JavaScript中如何使用正则表达式?有哪些注意事项?
A:JavaScript中创建正则表达式有两种方式:字面量语法 /pattern/flags 和构造函数 new RegExp(pattern, flags)。字面量语法更为简洁常用。核心方法包括:test() 返回布尔值表示是否匹配;match() 返回匹配结果数组;search() 返回第一个匹配的位置索引;replace() 执行替换操作;split() 按模式分割字符串。注意事项包括:使用 g 标志时,RegExp 对象的 lastIndex 属性会在多次调用 test()exec() 之间持续更新,可能导致意外行为;在字符串字面量中使用正则时,反斜杠需要双重转义;JavaScript的 \b 会将连字符 - 视为单词边界,这与其他语言不同。
Q:什么是灾难性回溯?如何避免正则表达式的性能问题?
A:灾难性回溯(Catastrophic Backtracking)是指正则表达式在匹配失败时,由于模式中存在大量重叠的可选路径,导致引擎进行指数级数量的回溯尝试,从而造成程序卡死或极度缓慢。典型的触发模式包括嵌套量词(如 (a+)+)和多个重叠的可选分支。避免性能问题的方法包括:避免使用嵌套量词,优先使用非贪婪模式;使用具体的字符类替代 .*;为量词设置合理的上限(如 {1,100} 而非 +);在可能的情况下使用锚点 ^$ 限定匹配范围;对于大文本匹配,考虑使用多步处理替代单个复杂正则。Go语言的RE2引擎不支持回溯,从根源上避免了这一问题。
Q:不同编程语言的正则表达式有什么区别?
A:虽然正则表达式的基本语法是通用的,但不同编程语言在实现细节上存在显著差异。JavaScript使用 /pattern/flags 字面量语法,支持 y(粘连)标志,但不支持后行断言(ES2018后已支持)。Python的 re 模块使用原始字符串 r'pattern' 避免转义问题,支持命名捕获组 (?P<name>...)。Go的 regexp 包基于RE2引擎,不支持回溯和零宽断言中的某些语法(如后行断言的变长模式)。Java的 java.util.regex 包中字符串需要双重转义(如 \\d),支持多种断言语法。PHP的PCRE扩展支持最完整的正则语法,包括递归模式和条件表达式。建议开发者在跨语言开发时,先查阅对应语言的正则文档,避免使用不支持的语法特性。