正则表达式在 JavaScript 和 Python 中均为引用类型对象,非基本数据类型;JS 中 /abc/ 是 RegExp 实例,typeof 为 "object",=== 比较返回 false;Python 中 re.compile() 返回 re.Pattern 对象,不可哈希且不支持值比较。

正则表达式在 JavaScript 中是 RegExp 对象
它不是基本数据类型(如 string、number、boolean),而是引用类型,即对象。哪怕你用字面量写成 /abc/,JS 引擎内部也会隐式创建一个 RegExp 实例。
验证方式很简单:
typeof /abc/ // "object" /abc/ instanceof RegExp // true Object.prototype.toString.call(/abc/) // "[object RegExp]"
注意:虽然字面量写法看起来像“原始语法”,但它不等价于字符串,也不能直接用 === 比较两个相同字面量的正则——每次都是新对象:
/abc/ === /abc/ // false
Python 里 re.compile() 返回的是 re.Pattern 对象
Python 没有原生正则字面量,所有正则操作都依赖 re 模块。调用 re.compile() 后返回的对象类型是 re.Pattern(Python 3.7+),属于标准库定义的类实例,明确是对象类型。
常见误判点:
import re r = re.compile(r'\d+') type(r) #isinstance(r, re.Pattern) # True r == re.compile(r'\d+') # False(对象身份不同)
即使你用 re.search() 这类函数直接传入字符串模式,底层仍会临时编译为 Pattern 对象——只是不暴露给你。
JSON(JavaScript Object Notation) 定义:一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。业内主流技术为其提供了完整的解决方案(有点类似于正则表达式,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换。JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。有需要的朋友可以下载看看
为什么不能当成基本类型用?关键在可变性与身份语义
正则对象携带状态,比如 lastIndex(JS 中启用 g 标志时)、编译后的匹配逻辑、捕获组结构等。这些都不能被值比较覆盖:
-
RegExp实例有flags、source属性,可读可改(部分只读) - Python 的
re.Pattern有pattern、flags、groups等只读属性,但对象本身不可哈希(不能做字典 key,除非显式缓存) - 跨调用复用正则对象能避免重复编译开销——这点只有对象模型才支持
如果你试图把正则当字符串传参再“比较内容”,大概率踩坑:没考虑标志位差异、Unicode 模式、或忽略大小写逻辑是否真等价。
容易被忽略的边界:正则字面量 vs 构造函数行为差异(JS)
JS 中 /abc/g 和 new RegExp('abc', 'g') 表面等效,但实际有三处关键区别:
- 字面量在代码解析阶段就编译;构造函数在运行时编译,可动态拼接,但也可能抛
SyntaxError - 构造函数的
pattern参数是字符串,反斜杠需双写:new RegExp('\\d+'),而字面量写/\d+/即可 - 字面量无法从变量注入标志位;
flags必须硬编码,而构造函数第二个参数可以是变量
这种差异导致很多人在模板字符串中拼正则时出错:
const keyword = 'test';
// ❌ 错误:反斜杠被字符串转义吃掉
const r1 = new RegExp('\b' + keyword + '\b', 'g'); // \b 变成退格符
// ✅ 正确:用 String.raw 或双反斜杠
const r2 = new RegExp('\b' + keyword + '\b', 'g');
const r3 = new RegExp(String.raw\b${keyword}\b, 'g');
对象本质决定了这些行为差异不是 bug,而是设计必然——毕竟你要操作的是一个具备生命周期和状态的实体,不是一串静态字符。










