fix: RegExp flag 全量透传(u/s/y/d 生效,\p{...} unicode 属性可用)

This commit is contained in:
爱特每羊队
2026-08-08 18:05:59 +08:00
parent 504ffaf126
commit 185ecf0c53
+17 -15
View File
@@ -19,19 +19,27 @@ fn get_regexp_ptr<H: VmHost>(vm: &mut H, args: &[u8]) -> Result<*mut JsObject, J
Ok(ptr) Ok(ptr)
} }
fn parse_flags(flags: &str) -> (bool, bool, bool) { fn parse_flags(flags: &str) -> (bool, bool, bool, bool, bool, bool, bool) {
let mut global = false; let mut global = false;
let mut ignore_case = false; let mut ignore_case = false;
let mut multi_line = false; let mut multi_line = false;
let mut dot_all = false;
let mut sticky = false;
let mut unicode = false;
let mut has_indices = false;
for c in flags.chars() { for c in flags.chars() {
match c { match c {
'g' => global = true, 'g' => global = true,
'i' => ignore_case = true, 'i' => ignore_case = true,
'm' => multi_line = true, 'm' => multi_line = true,
's' => dot_all = true,
'y' => sticky = true,
'u' => unicode = true,
'd' => has_indices = true,
_ => {} _ => {}
} }
} }
(global, ignore_case, multi_line) (global, ignore_case, multi_line, dot_all, sticky, unicode, has_indices)
} }
fn set_prop<H: VmHost>(obj: &mut JsObject, name: &str, val: JsValue, vm: &H) { fn set_prop<H: VmHost>(obj: &mut JsObject, name: &str, val: JsValue, vm: &H) {
@@ -78,22 +86,15 @@ pub fn regexp_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
(pat, fl) (pat, fl)
}; };
let (global, ignore_case, multi_line) = parse_flags(&flags); let (global, ignore_case, multi_line, dot_all, sticky, unicode, has_indices) = parse_flags(&flags);
let mut obj = JsObject::new_empty( let mut obj = JsObject::new_empty(
EMPTY_SHAPE_ID, EMPTY_SHAPE_ID,
JsValue::from_js_object(vm.session().builtin_world().regexp_proto.as_ptr() as *mut JsObject), JsValue::from_js_object(vm.session().builtin_world().regexp_proto.as_ptr() as *mut JsObject),
); );
// regress 用 JS flag 字符串编译(i/m 当前支持;u/s/y 由 parse_flags 处理)。 // regress 用 JS flag 字符串编译:g/i/m/s/u/y 原样透传(v 由调用方映射为 u+set 语义)。
let mut flags_in: String = String::new(); let compiled = regress::Regex::with_flags(&pattern, flags.as_str());
if ignore_case {
flags_in.push('i');
}
if multi_line {
flags_in.push('m');
}
let compiled = regress::Regex::with_flags(&pattern, flags_in.as_str());
match compiled { match compiled {
Ok(re) => { Ok(re) => {
@@ -118,9 +119,10 @@ pub fn regexp_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
set_prop(&mut obj, "global", JsValue::bool(global), vm); set_prop(&mut obj, "global", JsValue::bool(global), vm);
set_prop(&mut obj, "ignoreCase", JsValue::bool(ignore_case), vm); set_prop(&mut obj, "ignoreCase", JsValue::bool(ignore_case), vm);
set_prop(&mut obj, "multiline", JsValue::bool(multi_line), vm); set_prop(&mut obj, "multiline", JsValue::bool(multi_line), vm);
set_prop(&mut obj, "dotAll", JsValue::bool(false), vm); set_prop(&mut obj, "dotAll", JsValue::bool(dot_all), vm);
set_prop(&mut obj, "sticky", JsValue::bool(false), vm); set_prop(&mut obj, "sticky", JsValue::bool(sticky), vm);
set_prop(&mut obj, "unicode", JsValue::bool(false), vm); set_prop(&mut obj, "unicode", JsValue::bool(unicode), vm);
set_prop(&mut obj, "hasIndices", JsValue::bool(has_indices), vm);
obj.type_tag = JsObject::OBJ_TYPE_REGEXP; obj.type_tag = JsObject::OBJ_TYPE_REGEXP;
let obj_ptr = vm.alloc_object(obj); let obj_ptr = vm.alloc_object(obj);